论坛首页 Java企业应用论坛

(原创)Dubbo源码之消费者创建代理

浏览 1268 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2018-05-02  

ReferenceBean中

afterPropertiesSet方法:获取当前项目所有的具体配置项(Registry,Module,Application,Monitor)。
spring为bean复制的时候,调用getObject方法。

getObject方法:
调用get方法

get方法:
调用ReferenceConfig类中的init方法

ReferenceConfig中

init方法:
获取当前消费者全局配置,根据当前配置生成代理,具体配置项为:
side=consumer, 
application=demo-consumer,
methods=sayHello, 
dubbo=2.0.0, 
pid=6440, 
interface=com.alibaba.dubbo.demo.DemoService, 
timestamp=1481015195590

createProxy方法: 
创建临时路径
temp://localhost?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
通过注册中心配置拼装URL,执行loadRegistries方法,拼接的url结果为:
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&pid=6440&registry=zookeeper&timestamp=1481015705299
引用远程服务,调用RegistryProtocol类中的refer方法,参数为服务提供者的接口interface com.alibaba.dubbo.demo.DemoService以及由注册中心拼接的上面的URL。

RegistryProtocol中
refer方法:
通过RegistryFactory类的getRegistry方法,
URL修改为:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&pid=6440&timestamp=1481015705299
根据URL获取service服务key为zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService
通过URLzookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&pid=6440&timestamp=1481015705299
创建zookeeper客户端,并连接zk主机,将该registry缓存。执行doRefer方法,参数为
cluster,创建的集群策略对象默认使用AvailableCluster
registry,当前连接的注册中心对象
type,服务提供者接口interface com.alibaba.dubbo.demo.DemoService
url,zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&pid=6440&refer=application%3Ddemo-consumer%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D6440%26side%3Dconsumer%26timestamp%3D1481015195590&timestamp=1481015705299

doRefer方法:
创建RegistryDirectory对象,将RegistryDirectory对象中的routers中添加MockInvokersSelector对象
serviceType设置为:interface com.alibaba.dubbo.demo.DemoService
serviceKey设置为:com.alibaba.dubbo.registry.RegistryService
queryMap设置为:{side=consumer, application=demo-consumer, methods=sayHello, dubbo=2.0.0, pid=6440, interface=com.alibaba.dubbo.demo.DemoService, timestamp=1481015195590}
overrideDirectoryUrl设置为:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
serviceMethods设置为sayHello
设置registry对象为传来的registry,设置协议为dubbo。
根据本地URL等信息创建订阅URL:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
进入FailbackRegistry类中执行register方法。参数为消费者调用service的URL
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540

FailbackRegistry中
register方法:
缓存消费者调用service的URL,也就是消费者的描述消费行为的URL
向服务器端发送注册请求,执行doRegister方法,参数为消费行为URL

doRegister方法:
进入ZookeeperRegistry类中,create方法添加节点,分为持久节点与临时节点两种,其中持久节点路径为:
/dubbo/com.alibaba.dubbo.demo.DemoService/consumers
临时节点为:
/dubbo/com.alibaba.dubbo.demo.DemoService/consumers/consumer%3A%2F%2F192.168.10.107%2Fcom.alibaba.dubbo.demo.DemoService%3Fapplication%3Ddemo-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D10412%26side%3Dconsumer%26timestamp%3D1481070964540
与zk进行长连接以后,回到RegistryProtocol类中的doRefer方法中。

RegistryProtocol中
doRefer方法:将之前创建的directory执行订阅方法,directory.subscribe方法,参数为订阅URL
订阅URL为消费者消费行为URL的修改:
原:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
现:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
订阅执行FailbackRegistry类中的subscribe方法。

FailbackRegistry中
subscribe方法:
为该消费者的注册中心notified的属性添加监听类集合,key为消费者URL:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
value为new ConcurrentHashMap<URL, Set<NotifyListener>>(),Set集合中存放监听listener监听器。然后执行doSubscribe方法。

doSubscribe方法
参数为消费者消费行为URL与RegistryProtocol类中doRefer方法中创建的RegistryDirectory。执行ZookeeperRegistry类中的subscribe方法。

ZookeeperRegistry中
doSubscribe方法:
参数与FailbackRegistry中doSubscribe方法的参数一样。
通过消费者消费行为URL转化获得消费者对应的服务提供者的URL:
原:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
现:/dubbo/com.alibaba.dubbo.demo.DemoService/providers。
根据此目录获取绑定再zk上的监听器,zkListeners,如果没有,则在zkListeners上创建,格式为key-value,key为:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
value为new ConcurrentHashMap<NotifyListener, ChildListener>(),
listener相关变量:
1、ZookeeperRegistry类中的变量
zkListeners
类型为ConcurrentHashMap<URL, ConcurrentMap<NotifyListener, ChildListener>>
2、从1中获取到的listeners,通过url获取url为:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=13152&side=consumer&timestamp=1481164403391
类型为ConcurrentMap<NotifyListener, ChildListener> 
3、从2中获取到的zkListener,key为2中的NotifyListener,NotifyListener为传来的RegistryDirectory
整体梳理(消费者URL,(消费者所需的服务提供者的集合,监听器对象))
创建完监听器集合以及对应关系,执行zkClient.create方法,参数为/dubbo/com.alibaba.dubbo.demo.DemoService/providers和false,调用AbstractZookeeperClient中的create方法,false代表创建的是持久集合
添加之后,对该消费者在zk节点的加监听,执行zkClient.addChildListener方法,参数为消费者zk节点的path与listener,最终执行的是ZkclientZookeeperClient类中的addTargetChildListener方法,使用zkAPI的原生方法client.subscribeChildChanges(path, listener);
最后执行FailbackRegistry类中的notify方法,参数为
本地消费者URL:consumer://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575
描述消费者与注册中心的RegistryDirectory
URLS:
dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10568&side=provider&timestamp=1481250727882
empty://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=configurators&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575
empty://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575

FailbackRegistry中
notify方法跳转执行doNotify方法

doNotify方法:
最终执行AbstractRegistry中的notify方法

AbstractRegistry中:

notify方法:
执行RegistryDirectory中的notify

RegistryDirectory中:
notify方法:
执行refreshInvoker方法:
将传来的URL通过toInvokers方法转换为invoker,URL为:
dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10568&side=provider&timestamp=1481250727882

toInvokers方法:
因为之前没有获取过服务提供者的URL,所以缓存中没有,需要获取服务提供者,执行DubboProtocol类中的refer方法,

DubboProtocol中的
refer方法:
参数为:interface com.alibaba.dubbo.demo.DemoService
dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-consumer&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10868&side=consumer&timestamp=1481252071784
创建DubboInvoker
首先通过URL获取zkClient执行getClients方法,参数为上面的参数,执行initClient方法

initClient方法:
调用Exchangers.connect(url ,requestHandler)方法。
URL:dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-consumer&check=false&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10868&side=consumer&timestamp=1481252071784
创建NettyClient并连接远程服务端,将转换的invoker加入缓存。
回到RegistryDirectory中的refreshInvoker方法。回到RegistryProtocol中doRefer方法。

RegistryProtocol中
doRefer方法:
将封装了与服务提供者的URL以及注册中的directory加入到Cluster中,将Cluster伪装成invoker,将invoker整合为demoService的代理,默认代理为JavassistProxyFactory创建代理。
创建InvokerInvocationHandler,将真正的服务提供者invoker加入到InvokerInvocationHandler中

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics