太令人吃惊了,Dubbo 服务发布-原理解析就这么轻松自然的梳理完了!

服务发布-原理
第一个发布的动作:暴露本地服务
    Export dubbo service com.alibaba.dubbo.demo.DemoService to local registry, dubbo version: 2.0.0, current host: 127.0.0.1
第二个发布动作:暴露远程服务
    Export dubbo service com.alibaba.dubbo.demo.DemoService to url dubbo://192.168.100.38: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=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1
    Register dubbo service com.alibaba.dubbo.demo.DemoService url dubbo://192.168.100.38: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&monitor=dubbo%3A%2F%2F192.168.48.117%3A2181%2Fcom.alibaba.dubbo.registry.RegistryService%3Fapplication%3Ddemo-provider%26backup%3D192.168.48.120%3A2181%2C192.168.48.123%3A2181%26dubbo%3D2.0.0%26owner%3Dwilliam%26pid%3D8484%26protocol%3Dregistry%26refer%3Ddubbo%253D2.0.0%2526interface%253Dcom.alibaba.dubbo.monitor.MonitorService%2526pid%253D8484%2526timestamp%253D1473908495729%26registry%3Dzookeeper%26timestamp%3D1473908495398&owner=william&pid=8484&side=provider&timestamp=1473908495465 to registry registry://192.168.48.117:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.48.120:2181,192.168.48.123:2181&dubbo=2.0.0&owner=william&pid=8484&registry=zookeeper&timestamp=1473908495398, dubbo version: 2.0.0, current host: 127.0.0.1
第三个发布动作:启动netty
    Start NettyServer bind /0.0.0.0:20880, export /192.168.100.38:20880, dubbo version: 2.0.0, current host: 127.0.0.1
第四个发布动作:打开连接zk
    INFO zookeeper.ClientCnxn: Opening socket connection to server /192.168.48.117:2181
第五个发布动作:到zk注册
    Register: dubbo://192.168.100.38: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=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1
第六个发布动作;监听zk
    Subscribe: provider://192.168.100.38: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=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1
    Notify urls for subscribe url provider://192.168.100.38: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=8484&side=provider&timestamp=1473908495465, urls: [empty://192.168.100.38: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=8484&side=provider&timestamp=1473908495465], dubbo version: 2.0.0, current host: 127.0.0.1

暴露本地服务和暴露远程服务的区别是什么?
1.暴露本地服务:指暴露在用一个JVM里面,不用通过调用zk来进行远程通信。例如:在同一个服务,自己调用自己的接口,就没必要进行网络IP连接来通信。
2.暴露远程服务:指暴露给远程客户端的IP和端口号,通过网络来实现通信。


zk持久化节点 和临时节点有什么区别?
持久化节点:一旦被创建,触发主动删除掉,否则就一直存储在ZK里面。
临时节点:与客户端会话绑定,一旦客户端会话失效,这个客户端端所创建的所有临时节点都会被删除。

ServiceBean.onApplicationEvent
-->export()
  -->ServiceConfig.export()
    -->doExport()
      -->doExportUrls()//里面有一个for循环,代表了一个服务可以有多个通信协议,例如 tcp协议 http协议,默认是tcp协议
        -->loadRegistries(true)//从dubbo.properties里面组装registry的url信息
        -->doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) 
          //配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)
          -->exportLocal(URL url)
            -->proxyFactory.getInvoker(ref, (Class) interfaceClass, local)
              -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension("javassist");
              -->extension.getInvoker(arg0, arg1, arg2)
                -->StubProxyFactoryWrapper.getInvoker(T proxy, Class<T> type, URL url) 
                  -->proxyFactory.getInvoker(proxy, type, url)
                    -->JavassistProxyFactory.getInvoker(T proxy, Class<T> type, URL url)
                      -->Wrapper.getWrapper(com.alibaba.dubbo.demo.provider.DemoServiceImpl)
                        -->makeWrapper(Class<?> c)
                      -->return new AbstractProxyInvoker<T>(proxy, type, url)
            -->protocol.export
              -->Protocol$Adpative.export
                -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("injvm");
                -->extension.export(arg0)
                  -->ProtocolFilterWrapper.export
                    -->buildInvokerChain //创建8个filter
                    -->ProtocolListenerWrapper.export
                      -->InjvmProtocol.export
                        -->return new InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap)
                        -->目的:exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService, this=InjvmExporter
          //如果配置不是local则暴露为远程服务.(配置为local,则表示只暴露本地服务)
          -->proxyFactory.getInvoker//原理和本地暴露一样都是为了获取一个Invoker对象
          -->protocol.export(invoker)
            -->Protocol$Adpative.export
              -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("registry");
                -->extension.export(arg0)
                  -->ProtocolFilterWrapper.export
                    -->ProtocolListenerWrapper.export
                      -->RegistryProtocol.export
                        -->doLocalExport(originInvoker)
                          -->getCacheKey(originInvoker);//读取 dubbo://192.168.100.51:20880/
                          -->rotocol.export
                            -->Protocol$Adpative.export
                              -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("dubbo");
                              -->extension.export(arg0)
                                -->ProtocolFilterWrapper.export
                                  -->buildInvokerChain//创建8个filter
                                  -->ProtocolListenerWrapper.export
---------1.netty服务暴露的开始-------    -->DubboProtocol.export
                                      -->serviceKey(url)//组装key=com.alibaba.dubbo.demo.DemoService:20880
                                      -->目的:exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService:20880, this=DubboExporter
                                      -->openServer(url)
                                        -->createServer(url)
--------2.信息交换层 exchanger 开始-------------->Exchangers.bind(url, requestHandler)//exchaanger是一个信息交换层
                                            -->getExchanger(url)
                                              -->getExchanger(type)
                                                -->ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension("header")
                                            -->HeaderExchanger.bind
                                              -->Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))
                                                -->new HeaderExchangeHandler(handler)//this.handler = handler
                                                -->new DecodeHandler
                                                    -->new AbstractChannelHandlerDelegate//this.handler = handler;
---------3.网络传输层 transporter--------------------->Transporters.bind
                                                  -->getTransporter()
                                                    -->ExtensionLoader.getExtensionLoader(Transporter.class).getAdaptiveExtension()
                                                  -->Transporter$Adpative.bind
                                                    -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.remoting.Transporter.class).getExtension("netty");
                                                    -->extension.bind(arg0, arg1)
                                                      -->NettyTransporter.bind
                                                        --new NettyServer(url, listener)
                                                          -->AbstractPeer //this.url = url;    this.handler = handler;
                                                          -->AbstractEndpoint//codec  timeout=1000  connectTimeout=3000
                                                          -->AbstractServer //bindAddress accepts=0 idleTimeout=600000
---------4.打开断开,暴露netty服务-------------------------------->doOpen()
                                                            -->设置 NioServerSocketChannelFactory boss worker的线程池 线程个数为3
                                                            -->设置编解码 hander
                                                            -->bootstrap.bind(getBindAddress())
                                                -->new HeaderExchangeServer
                                                  -->this.server=NettyServer
                                                  -->heartbeat=60000
                                                  -->heartbeatTimeout=180000
                                                  -->startHeatbeatTimer()//这是一个心跳定时器,采用了线程池,如果断开就心跳重连。

                        -->getRegistry(originInvoker)//zk 连接
                          -->registryFactory.getRegistry(registryUrl)
                            -->ExtensionLoader.getExtensionLoader(RegistryFactory.class).getExtension("zookeeper");
                            -->extension.getRegistry(arg0)
                              -->AbstractRegistryFactory.getRegistry//创建一个注册中心,存储在REGISTRIES
                                -->createRegistry(url)
                                  -->new ZookeeperRegistry(url, zookeeperTransporter)
                                    -->AbstractRegistry
                                      -->loadProperties()//目的:把C:\Users\bobo\.dubbo\dubbo-registry-192.168.48.117.cache
                                                                                                                                                                        文件中的内容加载为properties
                                      -->notify(url.getBackupUrls())//不做任何事             
                                    -->FailbackRegistry   
                                      -->retryExecutor.scheduleWithFixedDelay(new Runnable()//建立线程池,检测并连接注册中心,如果失败了就重连
                                    -->ZookeeperRegistry
                                      -->zookeeperTransporter.connect(url)
                                        -->ZookeeperTransporter$Adpative.connect(url)
                                          -->ExtensionLoader.getExtensionLoader(ZookeeperTransporter.class).getExtension("zkclient");
                                          -->extension.connect(arg0)
                                            -->ZkclientZookeeperTransporter.connect
                                              -->new ZkclientZookeeperClient(url)
                                                -->AbstractZookeeperClient
                                                -->ZkclientZookeeperClient
                                                  -->new ZkClient(url.getBackupAddress());//连接ZK
                                                  -->client.subscribeStateChanges(new IZkStateListener()//订阅的目标:连接断开,重连
                                        -->zkClient.addStateListener(new StateListener() 
                                          -->recover //连接失败 重连
                                          
                        -->registry.register(registedProviderUrl)//创建节点
                          -->AbstractRegistry.register
                          -->FailbackRegistry.register
                            -->doRegister(url)//向zk服务器端发送注册请求
                              -->ZookeeperRegistry.doRegister
                                -->zkClient.create
                                  -->AbstractZookeeperClient.create//dubbo/com.alibaba.dubbo.demo.DemoService/providers/
                                                                      dubbo%3A%2F%2F192.168.100.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26
                                                                      application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3D
                                                                      com.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3
                                                                      Dwilliam%26pid%3D2416%26side%3Dprovider%26timestamp%3D1474276306353
                                    -->createEphemeral(path);//临时节点  dubbo%3A%2F%2F192.168.100.52%3A20880%2F.............
                                    -->createPersistent(path);//持久化节点 dubbo/com.alibaba.dubbo.demo.DemoService/providers
                                        
                                        
                        -->registry.subscribe//订阅ZK
                          -->AbstractRegistry.subscribe
                          -->FailbackRegistry.subscribe
                            -->doSubscribe(url, listener)// 向服务器端发送订阅请求
                              -->ZookeeperRegistry.doSubscribe
                                -->new ChildListener()
                                  -->实现了 childChanged
                                    -->实现并执行 ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
                                  //A
                                -->zkClient.create(path, false);//第一步:先创建持久化节点/dubbo/com.alibaba.dubbo.demo.DemoService/configurators
                                -->zkClient.addChildListener(path, zkListener)
                                  -->AbstractZookeeperClient.addChildListener
                                    //C
                                    -->createTargetChildListener(path, listener)//第三步:收到订阅后的处理,交给FailbackRegistry.notify处理
                                      -->ZkclientZookeeperClient.createTargetChildListener
                                        -->new IZkChildListener() 
                                          -->实现了 handleChildChange //收到订阅后的处理
                                              -->listener.childChanged(parentPath, currentChilds);
                                              -->实现并执行ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
                                              -->收到订阅后处理 FailbackRegistry.notify
                                    //B          
                                    -->addTargetChildListener(path, targetListener)第二步
                                      -->ZkclientZookeeperClient.addTargetChildListener
                                        -->client.subscribeChildChanges(path, listener)//第二步:启动加入订阅/dubbo/com.alibaba.dubbo.demo.DemoService/configurators
                        
                        -->notify(url, listener, urls)
                          -->FailbackRegistry.notify
                            -->doNotify(url, listener, urls);
                              -->AbstractRegistry.notify
                                -->saveProperties(url);//把服务端的注册url信息更新到C:\Users\bobo\.dubbo\dubbo-registry-192.168.48.117.cache
                                  -->registryCacheExecutor.execute(new SaveProperties(version));//采用线程池来处理
                                -->listener.notify(categoryList)
                                  -->RegistryProtocol.notify
                                    -->RegistryProtocol.this.getProviderUrl(originInvoker)//通过invoker的url 获取 providerUrl的地址
                                                                                                            
                                                                                                                                                                        
                                        
                       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值