(原创)自己跟踪Dubbo源码之提供者创建

ServiceBean中的

afterPropertiesSet方法:获取当前项目所有的具体配置项(Registry,Module,Application,Monitor)。

onApplicationEvent方法:初始化完容器以后,因为ServiceBean继承了ApplicationListener,所以会执行onApplicationEvent方法中。
执行onApplicationEvent方法中的export方法,获取该service其他配置项,如是否暴露等。

ServiceConFig中的
doExport方法:接着执行ServiceConFig中的doExport方法,预备暴露,修改暴露状态,获取该service其他配置项,如使用的协议,注册地址,获取接口类型等,
继续检查各种项目,将各个配置项组合生成AbstractServiceConfig,AbstractInterfaceConfig等组合类,检查完毕,并且AbstractServiceConfig等类整理完毕以后,执行真正的doExportUrls方法。

doExportUrls方法:
loadRegistries方法:将之前doExport方法中的注册配置项整理成RegistryConfig类,并且整理生成Service的注册URL
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997,
循环协议配置项,执行doExportUrlsFor1Protocol方法,参数为协议配置项与注册URL。

doExportUrlsFor1Protocol方法:
获取协议的name,如果为空,默认为dubbo协议。获取service本地Host的IP,查看IP是否是本地,如果是本地服务,则直接开启socket,获取serivce端口默认为20800,将解析的协议封装为ProtocolConfig对象存进map对象进行缓存,获取service接口的方法名称加以缓存。
生成service服务的URL:
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
根据暴露状态进行暴露,配置中没有注明scope,则进行service本地暴露,执行exportLocal方法。

exportLocal方法:将本地服务生成的URL作为参数传入,将service服务URL转换成本地service服务URL:
injvm://127.0.0.1/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=10000&side=provider&timestamp=1480988981014
进入protocol层,执行export方法,参数为invoker类,该invoker类包含真正的service实现类,接口,以及本地service服务URL。
生成invoker类,默认执行JavassistProxyFactory生成代理。生成完毕,执行ProtocolListenerWrapper类的export方法,参数为invoker。

ProtocolListenerWrapper类中
export方法:为invoker装饰,添加listener和filter。伪装成invoker返回ServiceConFig中的exportLocal方法。


ServiceConFig中的

doExportUrlsFor1Protocol方法:
生成最终的invoker参数为实际service类,类接口,以及修改后的注册URL
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997
将最终的invoker包含service代理类,注册URL(注册中心URL和本地服务URL拼接而成)进行导出,执行类RegistryProtocol的export方法,参数为最终invoker。

进入protocol层,

RegistryProtocol中的

export方法:
执行doLocalExport方法,参数为最终invoker

doLocalExport方法:
对invokerURL进行编码
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997
对整理protocal时获取的map中的export属性值进行编码export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014
整理对应service的provider的URL,
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
将此provider的URL作为key向本地缓存寻找是否有exporter。如果没有,将invoker封装为InvokerDelegete(包含invoker与本地provider的url)则生成最终暴露服务的exporter,暴露服务由DubboProtocol类的export方法进行,参数为InvokerDelegete。

DubboProtocol中
export方法:
将本地provider的URL转换为变量key,key为com.alibaba.dubbo.demo.DemoService:20880,将此key与传入的InvokerDelegete,以及exporterMap生成新的DubboExporter,通过ConcurrentHashMap进行缓存,执行开启本地netty服务openServer方法,参数为本地provider的URL:
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014

openServer方法:
将URL的host以及IP地址以及Port提取出来,192.168.10.107:20880作为key,本地缓存查找是否存在该server,没有则创建,server为dubbo定义的ExchangeServer类。创建server的方法名为createServer方法,参数为本地provider服务的URL:
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014

createServer方法:
首先对传过来的本地provider的URL进行修改,针对readonly事件
原:dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
现:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014

再对上面的URL进行修改,针对开启heartbeat
原:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
现:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014

获取默认的server开启方式为netty

继续修改URL,针对编码格式以及负载均衡的配置
原:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
现:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014


将最终修改的URL传给Exchangers进行bind,参数为最终URL与生成DubboProtocol类时创建的成员变量ExchangeHandler requestHandler = new ExchangeHandlerAdapter(),requestHandler 中存在回调函数reply。

Exchangers中

bind方法:
通过spi机制,获取继承了Exchanger接口的实现类,通过meta-inf文件夹下的com.alibaba.dubbo.remoting.exchange.Exchanger文件,获取内容:header=com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger,也就是实现类为HeaderExchanger

HeaderExchanger中:

bind方法中:
通过Transporters类进行bind,先生成HeaderExchangeHandler类,HeaderExchangeHandler类持有ExchangeHandler类,ExchangeHandler类来自于DubboProtocol类初始化生成的成员变量,ExchangeHandler持有最主要的InvokerDelegete,继续生成DecodeHandler,DecodeHandler持有HeaderExchangeHandler。将最终生成的DecodeHandler传给Transporters类,执行bind方法,
参数为provider的本地服务url,以及最终生成的DecodeHandler。DecodeHandler持有最重要的InvokerDelegete类。根据spi机制,默认使用NettyTransporter进行最终bind方法的执行。

NettyTransporter中
bind方法:
创建NettyServer类,参数为DecodeHandler与本地provider本地服务URL:
URL为dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014

NettyServer中
NettyServer构造方法:
创建线程名称,默认开头为“DubboServerHandler”,根据provider本地服务URL进行修改为DubboServerHandler-192.168.10.107:20880,将此线程名称加入到本地服务URL的属性中key为threadname。返回的结果线程名称与DecodeHandler一起进入ChannelHandlers类中的wrap方法。

ChannelHandlers中
wrap方法:
跳转到wrapInternal方法

wrapInternal方法:
根据spi机制,执行AllDispatcher类中的dispatch方法,生成AllChannelHandler类。

AllChannelHandler中:
AllChannelHandler构造方法:
跳转父类WrappedChannelHandler类的构造方法

WrappedChannelHandler中
WrappedChannelHandler构造方法:
根据spi机制,执行FixedThreadPool类中的getExecutor方法,参数为provider本地服务url

FixedThreadPool中
getExecutor方法:
根据provider本地服务url:dubbo://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&channel.readonly.sent=true&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&threadname=DubboServerHandler-192.168.10.107:20880&timestamp=1480988981014
以及URL中的参数列表:{owner=william, side=provider, heartbeat=60000, methods=sayHello, dubbo=2.0.0, loadbalance=roundrobin, pid=10000, interface=com.alibaba.dubbo.demo.DemoService, generic=false, codec=dubbo, application=demo-provider, channel.readonly.sent=true, anyhost=true, timestamp=1480988981014, threadname=DubboServerHandler-192.168.10.107:20880}
获取参数列表中的线程名称:DubboServerHandler-192.168.10.107:20880
获取默认的线程池线程数量:200
获取queues数量为:0
创建jdk,concurrent包中的new ThreadPoolExecutor线程池任务,参数为(threads=200,threads=200,根据queues数值取队列类型,0为SynchronousQueue,小于0为LinkedBlockingQueue,大于0指定数值的LinkedBlockingQueue)
创建完线程池之后回到WrappedChannelHandler的构造方法。创建SimpleDataStore对象,将字符串“java.util.concurrent.ExecutorService”,url的port,与线程池一起合并在该对象的map中。
接着进入AbstractServer类中

AbstractServer中
AbstractServer构造方法:
通过url以及handler封装成AbstractPeer类,通过url取得本地连接/192.168.10.107:20880,获取host0.0.0.0,拼接url/0.0.0.0:20880,执行NettyServer类中的doOpen方法开启nettyServer。

NettyServer中
doOpen方法:
开启默认的netty的log日志,继承自InternalLoggerFactory类,通过new ServerBootstrap(channelFactory);开启netty服务器。返回给DubboProtocol类中的createServer方法,返回openServer方法。将创建的nettyServer存放在DubboProtocol类的成员变量serverMap中进行缓存,key为“192.168.10.107:20880”。
返回export方法,将创建的DubboExporter类进行缓存,缓存在exporterMap中,key为“com.alibaba.dubbo.demo.DemoService:20880”,返回ProtocolFilterWrapper类中的export方法,执行filter过滤,返回RegistryProtocol类中的doLocalExport方法,将生成的Exporter与最初的Invoker进行绑定,再次封装成成Exporter,将Exporter类进行缓存,到RegistryProtocol类中的bounds中,key为provider的url:
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014

RegistryProtocol中

getRegistry方法:
参数originInvoker,原始invoker,包含信息如下:
com.alibaba.dubbo.demo.provider.DemoServiceImpl@5d99c6b5
com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory@5a5338df
interface com.alibaba.dubbo.demo.DemoService
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997
{owner=william, registry=zookeeper, backup=192.168.10.233:2181,192.168.10.234:2181, application=demo-provider, dubbo=2.0.0, pid=10000, export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014, timestamp=1480988471997}
com.alibaba.dubbo.common.bytecode.Wrapper1@2a225dd7
获取invoker中的注册中心URL地址:registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997
根据协议以及注册地址,修改URL地址
原URL:registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&registry=zookeeper&timestamp=1480988471997
现URL:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&timestamp=1480988471997
将最后的URL传入AbstractRegistryFactory类中的getRegistry方法


AbstractRegistryFactory中

getRegistry方法:
处理URL,将传过来的URL中对于service服务的URL去掉,只取前面的注册中心地址:
原:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&export=dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014&owner=william&pid=10000&timestamp=1480988471997
现:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
对该注册中心地址进行修改
原:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
现:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService
从缓存中查找注册中心,如果不存在,则执行createRegistry方法,参数为现URL,zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService,执行类为ZookeeperRegistryFactory,方法为createRegistry方法。

ZookeeperRegistryFactory中

createRegistry方法:
创建ZookeeperRegistry对象,参数为zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
与zookeeperTransporter对象,进入ZookeeperRegistry类的构造方法ZookeeperRegistry。进入AbstractRegistry类中,执行构造方法。

AbstractRegistry中

AbstractRegistry构造方法:
参数为zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
设置成员变量registryUrl为该参数URL,创建临时文件C:\Users\sea/.dubbo/dubbo-registry-192.168.10.232.cache与dubbo-registry-192.168.10.232.cache.lock
执行notify方法,参数为配置的zookeeper集群中的其他IPbackup=192.168.10.233:2181,192.168.10.234:2181

notify方法:
参数为配置的所有zk路径:
zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
zookeeper://192.168.10.233:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
zookeeper://192.168.10.234:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997
查看是否已经订阅,如果已经订阅,则获取所有相关的NotifyListener执行notify回调方法,生成注册中心失败的话,异步重试。返回ZookeeperRegistry类的ZookeeperRegistry构造方法。

ZookeeperRegistry中

ZookeeperRegistry构造方法:
根据URL的group属性创建zk节点的跟目录,group属性为dubbo,修改为/dubbo,赋值给ZookeeperRegistry类的成员变量root,通过zookeeperTransporter类的connect方法连接注册中心,参数为:
zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997


ZkclientZookeeperTransporter中

connect方法:
创建ZkclientZookeeperClient对象。

ZkclientZookeeperClient中:
ZkclientZookeeperClient构造方法:
将注册中心URL进行缓存,创建KeeperState.SyncConnected,获取url的中所有IP,192.168.10.232:2181,192.168.10.233:2181,192.168.10.234:2181
创建ZkClient节点,对客户端执行subscribeStateChanges方法。将client封装成ZkclientZookeeperClient类,将ZkclientZookeeperClient类封装成ZkclientZookeeperTransporter类,返回ZookeeperClient。
回到ZookeeperRegistry类中的ZookeeperRegistry构造方法。当前zk目录下节点存在dubbo,dubbo下存在节点com.alibaba.dubbo.demo.DemoService,com.alibaba.dubbo.demo.DemoService下有providers节点,


ZookeeperRegistry中
ZookeeperRegistry构造方法:
对返回的ZookeeperClient添加监听事件,存在AbstractZookeeperClient类中的stateListenersSet集合中,当状态为RECONNECTED(重新连接)时,执行recover方法,将该registry进行缓存于AbstractRegistryFactory类中的REGISTRIES中,key为zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService
返回RegistryProtocol类中的export方法,获取到已经与注册中心连接的Url,执行FailbackRegistry类中的register方法。

FailbackRegistry中
register方法:
参数URL:
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
将url参数进行缓存,执行doRegister方法,参数为该provider类的URL,执行ZookeeperRegistry类中的doRegister方法。

ZookeeperRegistry中
doRegister方法:
执行AbstractZookeeperClient类中的create方法。

AbstractZookeeperClient中
create方法:
将provider本地URL转换为类型文件路径的路径:
/dubbo/com.alibaba.dubbo.demo.DemoService/providers/dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014
判断是否是临时节点还是持久化节点,默认为持久化节点,递归执行ZkclientZookeeperClient类中的方法,调用原生zkClient的createPersistent方法,路径为/dubbo/com.alibaba.dubbo.demo.DemoService/providers,最底层目录为临时目录/dubbo/com.alibaba.dubbo.demo.DemoService/providers/dubbo%3A%2F%2F192.168.10.107%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D10000%26side%3Dprovider%26timestamp%3D1480988981014
返回RegistryProtocol类中的export方法。

RegistryProtocol中
export方法:
参数为
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
将URL替换为
provider://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
创建overrideSubscribeListener,向注册中心订阅Registry,进入FailbackRegistry类中的subscribe方法,将该服务提供者provider的overrideSubscribeListener进行缓存。

FailbackRegistry中
subscribe方法:
向服务器端发送订阅请求,参数为URL:
provider://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
以及该服务提供者provider的overrideSubscribeListener。执行ZookeeperRegistry类中的doSubscribe方法。

ZookeeperRegistry中
doSubscribe方法:
该服务提供者provider的URL添加进注册中心Listeners的列表中,在zk下创建节点/dubbo/com.alibaba.dubbo.demo.DemoService/configurators。执行notify方法,
参数为
provider://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
服务提供者provider的overrideSubscribeListener。进入AbstractRegistry类中notify方法中

AbstractRegistry中
notify方法:
将configurators节点下的所有url检出,执行该服务提供者下的overrideSubscribeListener。进入RegistryProtocol中的notify方法,覆盖已经有的服务地址。

回到RegistryProtocol中
export方法:
返回新的Exporter对象,过滤ProtocolListenerWrapper中的export方法。将最终的exporter导出
该对象包含:
com.alibaba.dubbo.registry.integration.RegistryProtocol@43f82e78
com.alibaba.dubbo.registry.integration.RegistryProtocol$ExporterChangeableWrapper@2a448449
com.alibaba.dubbo.registry.integration.RegistryProtocol$OverrideListener@753432a2
provider://192.168.10.107:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10000&side=provider&timestamp=1480988981014
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014
zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&owner=william&pid=10000&timestamp=1480988471997


最终回到ServiceConfig类中,doExportUrlsFor1Protocol方法中,并将URL进行缓存。
dubbo://192.168.10.107: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=10000&side=provider&timestamp=1480988981014

猜你喜欢

转载自287746074.iteye.com/blog/2421828