使用dubbo进行服务开发

DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。最近需要用到dubbo进行老平台的改造,老平台的示意图如下:

老平台

老平台中外部连接平台与核心数据库直接交互,而且也没有为内部应用预留接口,不利于内部的服务治理,所以按照下图进行平台的改造:

新平台

新平台在外部连接平台中添加了dubbo服务,为非核心应用提供接口。数据库操作也转而使用由dubbo构建的数据服务实现。

使用dubbo服务进行开发需要至少3部分:服务提供者,服务消费者,服务注册中心;本文将会介绍如何利用这3部分进行一个简单的服务开发(当然dubbo也可以进行更多的扩展,例如服务监控等等)。

1.服务注册中心。

服务注册中心已经有非常多的开源解决方案,例如zookeeper,simple等等。下载好zookeeper后运行bin\zkServer.cmd或(bin/zkServer.sh),如果没有报错就就已经成功启动了。

ZOOKEEPER

2.开发接口

在开发Provider和Customer之前,我们需要定义服务所要提供的接口,并在之后添加到Provider和Customer的依赖中。

1
2
3
4
5
6
7
package info.aviraer.dubbo_service_api;

public interface Service {

public int plus(int a, int b);

}

我们定义了一个Service接口,里面只有一个plus方法。Customer调用plus方法,传递a和b两个变量,Provider返回a+b的结果。

接口写完后新建两个项目Customer和Provider,将接口项目添加到这两个项目的依赖中。

3.开发Provider(服务提供者)

新建MAVEN项目,添加需要的依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>info.aviraer</groupId>
<artifactId>dubbo-service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>dubbo-service-provider</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- 添加Spring依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>

<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>

</dependencies>
</project>

在Spring配置文件中配置dubbo服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 服务实现bean -->
<bean id="service" class="info.aviraer.dubbo_service_provider.ServiceImpl" />

<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="service_provider" />

<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />

<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="info.aviraer.dubbo_service_api.Service" ref="service" />

</beans>

编写服务实现类:

1
2
3
4
5
6
7
8
9
10
package info.aviraer.dubbo_service_provider;

import info.aviraer.dubbo_service_api.Service;

public class ServiceImpl implements Service{

public int plus(int arg0, int arg1) {
return arg0 + arg1;
}
}

服务启动类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package info.aviraer.dubbo_service_provider;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"/info/aviraer/dubbo_service_provider/spring.xml"});
context.start();
System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟
context.close();
}
}

完成以上步骤,一个简单的Provider就开发完成了。

4.开发Customer(服务消费者)

导入依赖(和Provider相同)。

在Spring配置文件中配置dubbo服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">

<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="service_consumer" />

<dubbo:registry address="zookeeper://127.0.0.1:2181" />

<!-- 生成远程服务代理,可以像使用本地bean一样使用demoService -->
<dubbo:reference id="service"
interface="info.aviraer.dubbo_service_api.Service" />

</beans>

服务调用类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package info.aviraer.dubbo_service_customer;

import info.aviraer.dubbo_service_api.Service;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws Exception
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "/info/aviraer/dubbo_service_customer/spring.xml" });
context.start();
Service service = (Service)context.getBean("service");
System.out.println(service.plus(1, 1));
context.close();
}
}

这样Customer也开发完成。

5.测试

首先启动Zookeeper,之后启动Provider,最后启动Customer,返回正确结果就证明服务已经生效。

服务调用结果

源码下载:dubbo-service