• dubbo学习(三)实现细节


    部分图片和描述来自官方文档,非原创

    初始化过程细节

    解析服务

    解析服务是暴露服务(提供方 provider )和消费方(引用提供方的 service )的前一个步骤。

    回想我们如何使用dubbo的

    提供方

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	...
    	<dubbo:provider protocol="dubbo" port="-1"/>
    	<dubbo:service interface="com.general.msg.service.PushCommentMeMsgService" ref="pushCommentMeMsgService" version="2.0.0" retries="0" timeout="6000"/>
    	<dubbo:service interface="com.general.msg.service.MessageDetailService" ref="messageDetailService" version="1.0.0" retries="0" />
    	...
    
    	</beans>
    
    

    x消费方

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	...
        <dubbo:consumer	check="false"/>
        <dubbo:reference interface="com.general.business.service.IndexDataService" id="indexDataService" version="1.0.0"/>
        <dubbo:reference interface="com.general.business.service.AppCommentService" id="appCommentService" version="2.0.0"/>
        ...
    
    
    </beans>
    

    下面我们看一下Dubbo 如何对XML的服务进行解析。

    解析实现

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

    http://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
    http://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
    
    

    可以知道这是利用SPI机制加载这两个类,然后对XML 进行解析。

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

    这两个方法非常重要!!ServiceConfig.export()是暴露服务用的;ReferenceConfig.get()

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

    暴露服务

    1297993-20200303155308392-542944953.png

    大致的过程如上,我们来看一下官方的描述,向注册中心暴露服务:

    在有注册中心,需要注册提供者地址的情况下 [2],ServiceConfig 解析出的 URL 的格式为: registry://registry-host/org.apache.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0"),基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocol 的 export() 方法,将 export 参数中的提供者 URL,先注册到注册中心。再重新传给 Protocol 扩展点进行暴露: dubbo://service-host/com.foo.FooService?version=1.0.0,然后基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调用 DubboProtocol 的 export() 方法,打开服务端口。 整个时序图如下 : 1297993-20200303155800141-1023474408.jpg 对应的export 方法在图中已经标出,方框这是注册到注册中心去的过程。

    引用提供者服务

    引用和暴露过程差不多,见官方文档 。

    远程调用细节

    上一节将的是初始化的过程,这一节将会讲如何调用和消费的问题。

    概述

    假如存在

    //消费方 
    public class DemoClientAction {
     
        private DemoService demoService;
     
        public void setDemoService(DemoService demoService) {
            this.demoService = demoService;
        }
     
        public void start() {
            String hello = demoService.sayHello("world" + i);
        }
    }
    

    上面代码中的 DemoService 就是上图中服务消费端的 proxy,用户代码通过这个 proxy 调用其对应的 Invoker [5],而该 Invoker 实现了真正的远程服务调用。

    //提供方代码
    public class DemoServiceImpl implements DemoService {
     
        public String sayHello(String name) throws RemoteException {
            return "Hello " + name;
        }
    }
    
    
    

    上面这个类会被封装成为一个 AbstractProxyInvoker 实例,并新生成一个 Exporter 实例。这样当网络通讯层收到一个请求后,会找到对应的 Exporter 实例,并调用它所对应的 AbstractProxyInvoker 实例,从而真正调用了服务提供者的代码。Dubbo 里还有一些其他的 Invoker 类,但上面两种是最重要的。

    那么大概是如下的过程 : 1297993-20200303160936701-1017740085.jpg

    可以知道 invoker 起到了一个承上启下的作用,在提供方和消费方之前形成了一个桥梁。

    服务提供者暴露一个服务的详细过程

    1297993-20200303160249291-1586092265.jpg

    暴露过程也不能理解,主线就是 invoker ---> exporter对象的过程。

    服务消费者消费一个服务的详细过程

    1297993-20200303160158190-2024843830.jpg

    线程派发模型

    1297993-20200303161400814-362995203.jpg

    参考资料

    • http://dubbo.apache.org/zh-cn/docs/dev/implementation.html
  • 相关阅读:
    [ERROR] Terminal initialization failed; falling back to unsupported
    设计模式原则
    设计模式:概述
    INFO Dispatcher:42
    Exception occurred during processing request: id to load is required for loading
    Java编程基础篇第六章
    Spring (一)(未完~~~
    Spring MVC处理过程理解(一)
    Spring MVC源码解析(二)
    MyBatis拦截器(一)
  • 原文地址:https://www.cnblogs.com/Benjious/p/12402936.html
Copyright © 2020-2023  润新知