Dubbo原理分析
接触了dubbo框架已经接近一年,今天把dubbo框架的实现总结一下。
1.前言
未有dubbo之前,我们在应用与应用跨应用调用,一般可以采用基于TCP的socket来实现(当然也可以用netty或者httpclient),当采用这种调用方式,会有一个严重弊端,那就是当服务过多时,导致调用者与被调用者的关系链变得负责,用专业术语来说就是服务治理问题。而解决服务治理问题的核心方法就是使用注册中心。而dubbo就是在基于这种背景上实现的。
2.Dubbo原理分析
分析原理之前,我们先来看一下dubbo的架构图,如图:
dubbo的架构图并不复杂,概括性的总结就是
1.提供方(生产者)在启动时,将服务信息注册在注册中心
2.调用方(消费者)向注册中心订阅相关服务信息
3.注册中心返回服务提供者的列表给消费者,当服务信息有变化时,注册中心会通知提供方(消费者)
4.提供方(消费者)得到服务信息后,按照软负载均衡算法,调用相关服务
现在分析一下底层实现原理
2.1发布服务底层实现原理
从dubbo角度分析:
在提供方启动时,会读取dubbo配置文件,解析xml,得到映射成对象的bean对象,然后将bean对象转换为URL格式,将所有bean属性转成URL的参数,比如:registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”),基于扩展点的Adaptive机制,通过URL的“registry://”协议头识别,调用RegistryProtocol的export方法,将export参数中的提供者URL先注册到注册中心,再重新传给Protocol扩展点进行暴露:Dubbo://service-host/com.xxx.TxxService?version=1.0.0。基于扩展点的Adaptive机制,通过提供者URL的"dubbo://"协议头识别,就会调用DubboProtocol的export()方法,打开服务端口。
从注册中心的角度看,提供方启动时,将自己的服务信息注册在注册中心中,在注册中心会生成一个节点,具体形式是服务接口的权限定名为key,value为实际dubbo协议远程调用地址。这个节点是以临时+持久的方式存放。
2.2引用服务底层实现原理
调用者读取dubbo配置文件,解析xml,得到映射成对象的bean对象,然后将bean对象转换为URL格式,将所有bean属性转成URL的参数,比如解析出来的URL格式为registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”),基于扩展点protocol的adaptive机制,通过URL的“registry://”协议头识别,就会调用RegistryProtocol的refer方法,基于refer参数中的条件,查询提供者的URL,如:
Dubbo://service-host/com.xxx.TxxService?version=1.0.0。基于扩展点的adaptive机制,通过提供者URL的“dubbo://”协议识别,就会调用DubboProtocol的refer方法,得到提供者应用。然后RegistryProtocol将多个提供者引用,通过Cluster扩展点,伪装成单个提供者引用返回。
3.补充
在调用者得到应用后,就用采用本地rpc来调用服务,在这个步骤,dubbo设置了软负载均衡,提供了四种负载均衡策略,dubbo默认为第一种随机均衡策略
Random LoadBalance
- 随机,按权重设置随机概率。
- 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
- 轮循,按公约后的权重设置轮循比率。
- 存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
- 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
- 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
- 一致性Hash,相同参数的请求总是发到同一提供者。
- 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
- 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing。
- 缺省只对第一个参数Hash,如果要修改,请配置<dubbo:parameter key="hash.arguments" value="0,1" />
- 缺省用160份虚拟节点,如果要修改,请配置<dubbo:parameter key="hash.nodes" value="320" />