[dubbo]初始化过程和调用过程

dubbo是阿里的开源RPC中间件,前些年停止维护后,一些公司开始推出自己的改良版本,如当当网的dubbox,目前github star 5K+。后来,阿里重新开始维护dubbo,并且dubbo被纳入了Apache的顶级孵化项目,目前github star 32K+,dubbox的6倍多。所以,还是学习apache dubbo吧。

官网:http://dubbo.apache.org/zh-cn/

github:https://github.com/apache/dubbo

spring boot版本dubbo的依赖坐标:

    
      com.alibaba.boot
      dubbo-spring-boot-starter
    

 

本问主要涉及Dubbo两部分的说明:初始化过程和调用过程

============     初始化      =======================

springBoot对注解的处理,参考 [springBoot]三个主要特征的实现

  1. run
  2. 扫描入口类的注解,两个注解@EnableDubbo、@SpringBootApplication(略)
  3. springBoot对@Import注解标注的ImportSelector接口实现类,会执行ImportSelector.selectImports。返回一些类全路径列表,并对这些类进行递归扫描。EnableDubbo类型上又有两个注解:@EnableDubboConfig、@DubboComponentScan
  4. @EnableDubboConfig
    1. @EnableDubboConfig有注解@Import({ DubboConfigConfigurationSelector.class})
    2. DubboConfigConfigurationSelector执行selectImports返回DubboConfigConfiguration.Multiple或DubboConfigConfiguration.Single
    3. Multiple和Single绑定了dubbo的配置,和对应的配置类,如dubbo.application绑定ApplicationConfig.class
  5. @DubboComponentScan
    1. DubboComponentScan有注解@Import({ DubboComponentScanRegistrar.class})
    2. DubboComponentScanRegistrar是一个扫描注册器,它扫描包下的ServiceAnnotationBeanPostProcessor,与ReferenceAnnotationBeanPostProcessor一起注册到上下文中。这两个分别是ServiceBean和ReferenceBean的后置处理器。前者调用postProcessBeanDefinitionRegistry用来注册ServiceBean,ServiceBean实现了InitializingBean,在初始化时调用protocal.export向注册中心暴露自己。后者调用inject将ReferenceBean注入到依赖它的类的属性中。
    3. ReferenceAnnotationBeanPostProcessor.inject
    4. ReferenceAnnotationBeanPostProcessor.buildReferenceBean
    5. ReferenceBean.get()
    6. ReferenceBean的ref接口代理类为空,则init
    7. 将放入@EnableDubboConfig得到的配置信息放入map,ref = createProxy(map);
    8. AbstractProxyFactory.getProxy(invoker),接着用代理工厂创建代理,这里用到了类SPI的扩展机制,工厂类的实现类配置在META-INF/dubbo/internal/com.alibaba.dubbo.rpc.ProxyFactory中,见下图,可以看到有3种实现。第一种存根代理工厂,是服务提供端的代理工厂,后两者是消费端的代理工厂。区别是服务端的存根代理工厂会调用protocol.export,生成Exporter来暴露自己的服务。消费端的代理过程,包含了具体的调用逻辑。参数invoker,下面讲解[dubbo]初始化过程和调用过程_第1张图片
    9. Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)),获得代理
    10. ============invoker
    11. invoker根据场景有两者创建方式:@SPI("dubbo")Protocol.refer()和@SPI(FailoverCluster.NAME) Cluster.join()
    12. (@SPI(FailoverCluster.NAME) 从/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.Cluster文件中读取key为failover对应的类的全路径名)
    13. invoker可能是前置了Filter的调用链(ProtocolFilterWrapper),也可能是结合了容错策略的ClusterInvoker

留下一个疑问:Service是服务端提供的服务,Reference是客户端对服务的引用,StubProxyFactoryWrapper用于Reference创建代理,这个代理照理说是调用的过程,如JavaassistRpcProxyFactory,为什么会调用export暴露服务呢?什么时候用到StubProxyFactoryWrapper

============     调用过程      =======================

  1. 调用接口

  2. 进入代理的实现,InvocationHandler.invoke,(实现调用InvokerInvocationHandler)

  3. rpc回调结果result = invoker.invoke(new RpcInvocation(method, args)).recreate(),invocation为调用信息

  4. 通过list方法从Directory获取全部invoker

  5. 通过ExtensionLoader.getExtensionLoader扩展机制,获得负载均衡策略LoadBalance

  6. doInvoke(invocation, invokers, loadbalance)

  7. 然后走AbstractClusterInvoker子类,举个例子:FailoverClusterInvoker.select

  8. loadbalance.select选出唯一的invoker,进行请求

  9. 这里的invoker就是Protocol.refer()创建的,根据不同的协议有不同的实现[dubbo]初始化过程和调用过程_第2张图片

  10. ...先写到这吧,以上是消费端的调用

 

你可能感兴趣的:(dubbo)