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×tamp=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 originInvoker:DelegateProviderMetaDataInvoker实例(包装了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>()