Dubbo简介与实践

介绍

Dubbo 是阿里开源的分布式服务框架,架构如图所示:

1

其中,节点角色说明:

  1. Provider:暴露服务的服务提供者。
  2. Consumer:调用远程服务的服务消费者。
  3. Registry:服务注册与发现的注册中心。
  4. Monitor:统计服务的调用次数和调用时间的监控中心。
  5. Container:服务运行容器。

调用关系说明:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

Dubbo支持以下4种类型的注册中心:

  1. Multicast注册中心,不需要启动任何中心节点,只要广播地址一样,就可以互相发现;
  2. Zookeeper注册中心,服务提供者将服务信息写入Zookeeper,服务消费者从Zookeeper获取服务消息;
  3. Redis注册中心,服务提供者将服务信息写入Redis,服务消费者从Redis获取服务消息;
  4. Simple注册中心,注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致。

实践

Dubbo代码目前托管在GitHub上 ,将代码clone至本地目录dubbo下,其中dubbo-demo模块用于示例演示,包含了3个子模块:

  1. dubbo-demo-api;
  2. dubbo-demo-provider;
  3. dubbo-demo-consumer。

dubbo-demo-api说明

dubbo-demo-api定义示例服务接口DemoService:

1
2
3
4
5
6
7
package com.alibaba.dubbo.demo;

public interface DemoService {

String sayHello(String name);

}

dubbo-demo-provider说明

dubbo-demo-provider是示例服务提供者,其中,DemoServiceImpl类实现DemoService接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.alibaba.dubbo.demo.provider;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.alibaba.dubbo.demo.DemoService;
import com.alibaba.dubbo.rpc.RpcContext;

public class DemoServiceImpl implements DemoService {

public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress();
}

}

在Spring上下文中配置DemoServiceImpl实例,并将该服务通过Dubbo暴露出来:

1
2
3
4
5
6
7
8
9
10
11
12
<?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-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />

<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />

</beans>

dubbo-demo-consumer说明

dubbo-demo-consumer是示例服务消费者,其中,DemoAction类的start方法每隔2秒调用一次DemoService的sayHello方法:

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
package com.alibaba.dubbo.demo.consumer;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.alibaba.dubbo.demo.DemoService;

public class DemoAction {

private DemoService demoService;

public void setDemoService(DemoService demoService) {
this.demoService = demoService;
}

public void start() throws Exception {
for (int i = 0; i < Integer.MAX_VALUE; i ++) {
try {
String hello = demoService.sayHello("world" + i);
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " + hello);
} catch (Exception e) {
e.printStackTrace();
}
Thread.sleep(2000);
}
}

}

在Spring上下文中配置DemoAction实例,引用Dubbo暴露出来的接口:

1
2
3
4
5
6
7
8
9
10
11
<?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-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" />

</beans>

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<bean class="com.alibaba.dubbo.demo.consumer.DemoAction" init-method="start">
<property name="demoService" ref="demoService" />
</bean>

</beans>

启动服务提供者和服务消费者

修改dubbo-demo-provider和dubbo-demo-consumer中的src/main/assembly/conf/dubbo.properties,使用Zookeeper注册中心(需要先安装、启动Zookeeper):

1
dubbo.registry.address=zookeeper://xxx.xxx.xxx.xxx:2181

修改后,在dubbo-demo下执行Maven构建:

mvn clean install -Dmaven.test.skip

构建成功后,启动服务提供者:

cd dubbo-demo-provider/target
tar -zxvf dubbo-demo-provider-2.5.4-SNAPSHOT-assembly.tar.gz
cd dubbo-demo-provider-2.5.4-SNAPSHOT/bin
./start.sh

启动服务消费者:

cd dubbo-demo-consumer/target
tar -zxvf dubbo-demo-consumer-2.5.4-SNAPSHOT-assembly.tar.gz
cd dubbo-demo-consumer-2.5.4-SNAPSHOT/bin
./start.sh

启动后,可以查看Zookeeper目录,如图所示:
1
其中:

  1. 服务提供者向/dubbo/com.alibaba.dubbo.demo.DemoService/providers目录下写入自己的URL地址。
  2. 服务消费者订阅/dubbo/com.alibaba.dubbo.demo.DemoService/providers目录下的提供者URL地址,并向/dubbo/com.alibaba.dubbo.demo.DemoService/consumers目录下写入自己的URL地址。

查看服务消费者日志文件logs/stdout.log:
1
服务消费者每隔2秒输出一次,远程服务调用正常。

启动监控中心

dubbo下的dubbo-simple模块包含dubbo-monitor-simple子模块,修改dubbo-monitor-simple中的src/main/assembly/conf/dubbo.properties,使用Zookeeper注册中心:

1
dubbo.registry.address=zookeeper://xxx.xxx.xxx.xxx:2181

修改后,在dubbo-monitor-simple下执行Maven构建:

mvn clean install -Dmaven.test.skip

构建成功后,启动监控中心:

cd target
tar -zxvf dubbo-monitor-simple-2.5.4-SNAPSHOT-assembly.tar.gz
cd dubbo-monitor-simple-2.5.4-SNAPSHOT/bin
./start.sh

启动后,浏览器下打开,如图所示:
1
从中,可以查看到已有的应用及其依赖关系,已有的服务及其提供者、消费者等信息。