Dubbo 服务暴露总结

Service Export Summary

Posted by Jay on March 3, 2019

Dubbo 服务暴露总结

服务提供端配置:

<!-- 提供方应用信息用于计算依赖关系 -->
<dubbo:application name="demo-provider"/>
	
<!-- 使用zookeeper注册中心并使用zkClient客户端zk根节点为dubbo_test -->
<dubbo:registry protocol="zookeeper" address="localhost:2181" client="zkclient" group="dubbo_test"/>

<!-- 用dubbo协议在20881端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20881"/>

<!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl2"/>

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>

一、ServiceBean

1.继承实现关系

2.最终的ServiceBean实例
String id = com.alibaba.dubbo.demo.DemoService
ApplicationContext applicationContext = ClassPathXmlApplicationContext实例
String beanName = com.alibaba.dubbo.demo.DemoService
String interfaceName = com.alibaba.dubbo.demo.DemoService
Class<?> interfaceClass = interface com.alibaba.dubbo.demo.DemoService
boolean supportedApplicationListener = true
T ref = DemoServiceImpl2实例
String path = com.alibaba.dubbo.demo.DemoService
List<URL> urls: ["dubbo://172.16.132.166:20881/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&bind.ip=172.16.132.166&bind.port=20881&cellinvokemode=sharing&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=76358&side=provider&timestamp=1550994444617"]
List<Exporter<?>> exporters:[
  ListenerExporterWrapper实例
	  InjvmExporter实例
	    String key:com.alibaba.dubbo.demo.DemoService
	    Map<String, Exporter<?>> exporterMap: {"com.alibaba.dubbo.demo.DemoService ", 当前的InjvmExporter实例}
	    Invoker invoker经过Filter包装的AbstractProxyInvoker实例
  RegistryProtocol返回的新的Exporter实例
    Exporter exporter: ExporterChangeableWrapper<T> exporter实例
      Invoker originInvokerDelegateProviderMetaDataInvoker实例(包装了AbstractProxyInvoker实例
      	invoker: AbstractProxyInvoker实例
      	metadata: ServiceBean实例
      Exporter exporter: ListenerExporterWrapper实例
      	exporter: DubboExporter实例
    Registry registry: ZookeeperRegistry实例
]

ApplicationConfig application:
-- id = demo-provider
-- name = demo-provider

List<RegistryConfig> registries = [
    RegistryConfig:
    -- id = com.alibaba.dubbo.config.RegistryConfig
    -- protocol = zookeeper
    -- address = localhost:2181
    -- client = zkclient
    -- group = dubbo_test
]

List<ProtocolConfig>  protocols = [ 
    ProtocolConfig: 
    -- id = dubbo
    -- name = dubbo
    -- port = 20881    
]

二、调用简图

三、代码调用链

ServiceBean.onApplicationEvent(ContextRefreshedEvent event)
-->ServiceConfig.export()
  -->doExport()
    -->doExportUrls()
      -->loadRegistries(boolean provider) // 生成注册中心URL
      -->doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs)
        -->Wrapper.getWrapper(Class<?> c)
            -->makeWrapper(Class<?> c)
        -->new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map)
        <!-- 本地暴露 -->
        -->exportLocal(url)
          //1.1 将实现类ref封装成Invoker
          -->JavassistProxyFactory.getInvoker(T proxy, Class<T> type, URL url)
            -->Wrapper.getWrapper(Class DemoServiceImpl2)
            -->new AbstractProxyInvoker<T>(proxy, type, url)
          //1.2 将Invoker暴露为Exporter
          -->ProtocolListenerWrapper.export(Invoker<T> invoker)
            -->ProtocolFilterWrapper.export(Invoker<T> invoker)
              -->buildInvokerChain(final Invoker<T> invoker, key:"service.filter", group:"provider")
              -->InjvmProtocol.export(Invoker<T> invoker)
                -->new InjvmExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap)
          -->List<Exporter<?>> exporters.add(上述导出的exporter)
        <!-- 远程暴露 -->
        //2.1 将实现类ref封装成Invoker
        -->JavassistProxyFactory.getInvoker(T proxy, Class<T> type, URL url)
          -->Wrapper.getWrapper(Class DemoServiceImpl2)
          -->new AbstractProxyInvoker<T>(proxy, type, url)
        -->DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
        -->RegistryProtocol.export(final Invoker<T> originInvoker)
          //2.2 将invoker转化为exporter
          -->doLocalExport(originInvoker)
            -->new InvokerDelegete(Invoker<T> invoker, URL url)
            -->ProtocolListenerWrapper.export(Invoker<T> invoker)
              -->ProtocolFilterWrapper.export(Invoker<T> invoker)
                -->buildInvokerChain(final Invoker<T> invoker, String key, String group)
                -->DubboProtocol.export(Invoker<T> invoker)
                  -->new DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap)
                  //2.3 开启netty服务端监听客户端请求
                  -->openServer(URL url)
                    -->createServer(URL url)
                        -->HeaderExchanger.bind(URL url, ExchangeHandler handler)
                          -->new DecodeHandler(new HeaderExchangeHandler(handler)))
                            -->NettyTransporter.bind(URL url, ChannelHandler listener)
                              -->new NettyServer(URL url, ChannelHandler handler)
                                -->ChannelHandler.wrapInternal(ChannelHandler handler, URL url)
                                  -->new MultiMessageHandler(new HeartbeatHandler(new AllChannelHandler(handler,url)))
                                -->getChannelCodec(url)
                                -->doOpen() //开启netty服务
                          -->new HeaderExchangeServer(Server server)
                            -->startHeatbeatTimer()
            -->new ExporterChangeableWrapper(Exporter<T> exporter, Invoker<T> originInvoker)
          //2.4 创建Registry:创建zkclient,连接zk
          -->RegistryProtocol.getRegistry(final Invoker<?> originInvoker)
            -->AbstractRegistryFactory.getRegistry(URL url)
              -->ZookeeperRegistryFactory.createRegistry(URL url)
                -->new ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter)
                  -->ZkclientZookeeperTransporter.connect(URL url)
                    -->new ZkclientZookeeperClient(URL url)
                      -->new ZkClientWrapper(url.getBackupAddress(), 30000)
            -->AbstractRegistryFactory.Map<String, Registry>
          //2.5 向注册中心注册服务
          -->registryFactory.getRegistry(registryUrl)
          -->registry(ZookeeperRegistry).register(registedProviderUrl)
            -->FailbackRegistry.register(URL url)
              -->AbstractRegistry.register(URL url)
              -->ZookeeperRegistry.doRegister(URL url)
                -->AbstractZookeeperClient.create(String path, boolean ephemeral)
                  -->ZkclientZookeeperClient.createEphemeral(String path)
                    -->ZkClientWrapper.createEphemeral(String path)
                      -->org.I0Itec.zkclient.ZkClient.createEphemeral(final String path)
          //2.6 订阅提供者override数据
          -->registry(ZookeeperRegistry).subscribe(overrideSubscribeUrl, overrideSubscribeListener)
            -->FailbackRegistry.subscribe(URL url, NotifyListener listener)
              -->AbstractRegistry.subscribe(URL url, NotifyListener listener)
              -->ZookeeperRegistry.doSubscribe(final URL url, final NotifyListener listener)
          //2.7 创建新的Exporter实例
          -->new Exporter<T>()