Dubbo源码分析:Dubbo使用分析(一)
Dubbo源码分析:Dubbo使用分析(一)
Dubbo框架官方文档:http://dubbo.apache.org/#!/docs/user/quick-start.md?lang=zh-cn
我这里引入的版本是2.5.4,因为这个版本注释比较详细,后面的版本中,注释都被Apache给去掉了,可能会做源码修改。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.4</version>
</dependency>
* 引入zookeeper包
* 引入zkclient包,groupId:com.101tec
* 如果版本高于2.5.4需要引入curator-framework、curator-recipes包,groupId:org.apache.curator;不然会出错
![Image 1][]
新建一个Project项目,在Project下创建三个Module项目
- dubbo-client 调用远程服务的服务消费方,引用dubbo-interface中的接口;从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- dubbo-service 暴露服务的服务提供方,引用dubbo-interface接口,对接口进行实现;
- dubbo-interface 定义了需要暴露的服务;抽象到公共的接口里;
Dubbo-Service 发布服务需要配置的基本信息:
dubbo-service.xml
* dubbo:application 配置当前的应用信息 如:name="dubbo-service";
* dubbo:registry 配置连接注册中心的信息,消费端与服务端报纸一致; 如:address="zookeeper://127.0.0.1:2181"这里是连接Zookeeper注册中心的配置,
Dubbo提供的注册中心有四种:
* 1. Zookeeper 也是推荐使用的注册中心
* 2. Multicast 广播注册中心
* 3. Redis 使用 Redis 的 Key/Map 结构存储数据
* 4. Simple registry="N/A",Simple 注册中心本身就是一个普通的 Dubbo 服务;
* dubbo:protocol 用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受 如:name="dubbo" port="20880"
* 这里的协议是服务发布的协议,Dubbo提供的服务发布协议有,dubbo、rmi、hession、http、webservice、、、等等
* dubbo:service 用于暴露一个服务,
* dubbo:method 用于暴露一个服务里的具体方法
* dubbo:reference 用于创建一个远程服务代理,用于消费端(dubbo-client)
Dubbo服务端发布服务与消费端调用服务的流程:
* Dubbo 底层是基于Netty完成远程通信,基于TCP协议进行数据交互;
* 发布服务的时候,把协议、ip,端口号透明出去,如:dubbo://192.168.xxx:20880,
然后在Zookeeper创建一个znode节点;
* 消费端通过订阅Zookeeper拿到协议地址,通过ip地址与端口号找到发布的服务;根据interface接口,
找到服务端的实现类Bean,通过bean反射调用对应的实例,最后把结果返回过来,
中间有数据的序列化与反序列化,Dubbo默认的是hession序列化;
* 我们的服务端与Zookeeper建立连接,会在Zookeeper中创建dubbo文件夹==>
文件夹下创建对应的接口文件夹,如果有多个接口会创建多个对应的文件目录==>
在下面会创建四个文件夹依次是consumer、provider、router、configuration,
这个四个目录,分别保存有不同的信息
* 当我们服务端连接Zookeeper发布一个服务时,会与Zookeeper建立一个session会话,
并在Zookeeper上创建一个临时节点,如果会话断开一段时间里,临时节点会被删除,
而持久化节点是不会被删除的;
* 客户端去消费时,会获取IHello目录下的所有节点,当目录子节点发生变化时,
Zookeeper会有一个watcher事件通知发送给客户端,客户端拿到地址列表后,
根据具体的地址去连接服务。而且Zookeeper的watcher机制是一次性,如果需要长期通知,
需要循环订阅;
* 客户端获取地址列表之后会进行本地缓存;saveProperties(url);
如何快速启动Dubbo服务:
Dubbo支持的容器有,Spring container,Jetty container(2.6之后去掉了),Log4j container;
com.alibaba.dubbo.container.Main.main(args);快速启动服务;Dubbo默认情况下使用的Spring容器来启动服务;
也可以指定容器启动服务Main.main(“spring”,“log4j”);
如果使用快速启动服务的main方法,需要把dubbo-service配置指定的目录下,
因为dubbo默认加载路径就是resources==>META-INF/service/dubbo-service.xml这里;
多协议支持:
* 发布两种协议,每种协议需要进行声明:
* 同一个服务可以注册多个协议,在Zookeeper的provider目录下创建两个不同的znode节点,节点的协议和端口不同;
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 用hessian协议在8080端口暴露服务 -->
<dubbo:protocol name="hessian" port="8080"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service
interface="com.tongqin.distributed.api.IHello"
ref="demoService" protocol="dubbo,hessian" />
多注册中心支持:
同一个服务指定registry=“指定注册中心id”配置不同,会在不同的注册中心去注册服务;
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry id="mul" address="multicast://224.5.6.7:1234" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry id="zk" address="zookeeper://127.0.0.1:2181" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service
interface="com.tongqin.distributed.api.IHello"
ref="demoService" registry="zk" />
客户端调用服务
通过Spring容器加载dubbo的xml配置
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(dubbo-client.xml);
context.start();
demoService:服务发布是取得别名需要保持一致;
IHello hello = context.getBean(demoService,IHello.class);
System.out.println(hello.sayHello(change));
[Image 1]:
还没有评论,来说两句吧...