• Home
  • Articles
    • 日志
    • 妍小言
    • 舒小书
    • 浩然说
    • 生活日记
  • All Tags

Dubbo架构简述

18 Nov 2017

Reading time ~1 minute

全局入口 spring schema handler

spring handler:com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler,定义了不同元素的解析器与映射的类。比如dubbo:reference对应ReferenceBean,dubbo:service对应ServiceBean。

provider侧

  • 读取spring配置,dubbo会将spring xml中的dubbo:service元素通过预先定义好的解析器封装成一个ServiceBean,这是一个service的入口。
  • ServiceBean实现了spring的ApplicationListener接口,用来监听spring上下文事件。Dubbo响应了ContextRefreshedEvent事件,在上下文刷新之后执行导出provider动作。
  • 执行导出操作,需要两个信息:
    1. 通信协议信息,用来指定consumer和provider间的通信方式以及信息。
    2. 注册中心信息,用来往对应的注册中心注册provider url。
  • com.alibaba.dubbo.config.ServiceConfig#doExportUrls生成registry URL以及provider URL,并将provider URL作为registry URL的export参数绑定。根据registry URL的协议registry://拿到对应的RegistryProtocol并调用其export方法。
  • com.alibaba.dubbo.registry.integration.RegistryProtocol#export主要完成两件事情:
    1. 作为provider,使用定义好的通信协议来暴露服务,如dubbo,http,rmi等。
      • 从registry URL的export参数来获取provider URL。
      • 通过provider URL的协议来获取其对应的协议处理类并调用export方法。
    2. 使用registry URL中的registry参数作为注册中心协议替换原来的registry://协议
      • 通过新的registry URL的协议头,拿到相应的com.alibaba.dubbo.registry.Registry实例并调用其com.alibaba.dubbo.registry.RegistryService#register方法,比如向zookeeper新建临时节点。
  • 以上,就是provider侧的执行流程简述。

consumer侧

  • 同样的,dubbo会将dubbo:reference封装成一个ReferenceBean,但与provider不同,consumer实现了org.springframework.beans.factory.FactoryBean接口,初始化的流程推迟到了调用org.springframework.beans.factory.FactoryBean#getObject时。
  • 生成registry URL,暂时指定协议为registry://,并将实际协议作为registry参数的值绑定在URL上。
  • 通过registry URL的协议registry://,得到相应RegistryProtocol,然后调用其com.alibaba.dubbo.registry.integration.RegistryProtocol#refer方法来获取provider引用。
  • 更新registry URL协议。
  • 通过registry URL获取相应的com.alibaba.dubbo.registry.Registry。
  • com.alibaba.dubbo.registry.integration.RegistryDirectory。
    • RegistryDirectory通过registry URL和接口类型生成和命名。
    • RegistryDirectory用来封装所有的invoker地址信息以及路由信息等。
    • 负责通过provider URL中的协议信息获取相应的链接协议处理类并调用refer()方法以获取Invoker对象。
  • 生成订阅URL,协议为consumer://,通过registry URL获取相应的注册中心,向注册中心注册consumer URL。
  • 调用对应的注册中心的subscribe方法,com.alibaba.dubbo.registry.RegistryService#subscribe。
  • 通过调用com.alibaba.dubbo.registry.integration.RegistryDirectory#notify,最终会将provider URL保存到相应的RegistryDirectory中。
  • 可以查看com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe。

请求调用

  • 默认使用JDK动态代理模式来获取实际执行类。
  • 实际执行对象则是com.alibaba.dubbo.registry.integration.RegistryProtocol#refer返回的Invoker对象。
  • 最终会执行com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker#invoke方法。
  • 从RegistryDirectory中获取Invoker List。
  • 通过负载均衡从Invoker List中获取一个Invoker。
  • 拿到对应的链接协议Invoker实例,执行远程调用。

  • 注意,consumer实例是由com.alibaba.dubbo.registry.integration.RegistryProtocol#refer生成的,而用来执行远程链接处理远程协议的refer()方法则是由RegistryDirectory负责调用的。

以上只是dubbo架构很小的一部分,更多的信息大家可以通过阅读dubbo源码获取 dubbo源码地址。



dubbo