导航

Dubbo 服务暴露注册流程

Posted on 2016-04-13 10:56  蝈蝈俊  阅读(8632)  评论(0编辑  收藏  举报

Dubbo的应用会在启动时完成服务注册或订阅(不论是生产者,还是消费者)如下图所示。

image

  • 图中小方块Protocol, Cluster, Proxy, Service, Container, Registry, Monitor代表层或模块,蓝色的表示与业务有交互,绿色的表示只对Dubbo内部交互。
  • 图中背景方块Consumer, Provider, Registry, Monitor代表部署逻辑拓普节点。
  • 图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用。
  • 图中只包含RPC的层,不包含Remoting的层,Remoting整体都隐含在Protocol中。

整个服务初始化的过程细节如下:

解析服务

配置信息

在配置文件中,所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。

相关信息可以参考: Dubbo中对Spring配置标签扩展(http://www.cnblogs.com/ghj1976/p/5379332.html

以 dubbo-demo-provider 为例, 它的配置文件如下:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
   
    <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
   
    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />
   
</beans>

com.alibaba.dubbo.demo.provider.DemoServiceImpl 是服务实现类。

com.alibaba.dubbo.demo.DemoService 是服务需要实现的接口。

配置文件的解析过程

  • 基于dubbo.jar内的META-INF/spring.handlers配置,Spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler。
  • 所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。

每个service方法的配置会解析成对应的 com.alibaba.dubbo.config.spring.ServiceBean<T> 类的实例。

具体请参考:Dubbo中对Spring配置标签扩展 (http://www.cnblogs.com/ghj1976/p/5379332.html

 

配置文件对应的配置类的关系图如下:

 

image

根据 Spring Bean 的生命周期(http://www.cnblogs.com/ghj1976/p/5383743.html

在 afterPropertiesSet 后, 会调用到 ServiceConfig.export() 。

image

生产者在ServiceConfig.export()或消费者在ReferenceConfig.get()初始化时,将Bean对象转换URL格式,所有Bean属性转成URL的参数。

image

它的调用堆栈如下图:

image

 

然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露或引用。

image

 image

 

public interface Protocol {

/**
* 暴露远程服务:<br>
* 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
* 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。<br>
* 3. export()传入的Invoker由框架实现并传入,协议不需要关心。<br>
*
* @param <T> 服务的类型
* @param invoker 服务的执行体
* @return exporter 暴露服务的引用,用于取消暴露
* @throws RpcException 当暴露服务出错时抛出,比如端口已占用
*/
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;