Dubbo实现方案总览

简介: 从这篇文章开始,我们就开始深入到 Dubbo 的实现细节中,本文旨在一个较高的层面上总览 Dubbo 的实现方案。

引言

从这篇文章开始,我们就开始深入到 Dubbo 的实现细节中,本文旨在一个较高的层面上总览 Dubbo 的实现方案,其他 Dubbo 相关文章均收录于 <Dubbo系列文章>

总览

首先,我们简单的介绍一下各个功能点的实现,然后再深入代码中,详细分析每个功能点的细节。

解析服务

基于 dubbo.jar 内的 META-INF/spring.handlers 配置,Spring 在遇到 dubbo 名称空间时,会回调 DubboNamespaceHandler。

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

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

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

暴露服务

在没有注册中心,直接暴露提供者的情况下,ServiceConfig 解析出的 URL 的格式为: dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过 URL 的 dubbo:// 协议头识别,直接调用 DubboProtocol的 export() 方法,打开服务端口。

在有注册中心,需要注册提供者地址的情况下,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() 方法,打开服务端口。
rpc-export
上图是服务提供者暴露服务的主过程:

首先 ServiceConfig 类拿到对外提供服务的实际类 ref(如:HelloWorldImpl),然后通过 ProxyFactory 类的 getInvoker 方法使用 ref 生成一个 AbstractProxyInvoker 实例,到这一步就完成具体服务到 Invoker 的转化。接下来就是 Invoker 转换到 Exporter 的过程。

Dubbo 处理服务暴露的关键就在 Invoker 转换到 Exporter 的过程,上图中的红色部分。

Dubbo 协议的 Invoker 转为 Exporter 发生在 DubboProtocol 类的 export 方法,它主要是打开 socket 侦听服务,并接收客户端发来的各种请求,通讯细节由 Dubbo 自己实现。

RMI 协议的 Invoker 转为 Exporter 发生在 RmiProtocol类的 export 方法,它通过 Spring 或 Dubbo 或 JDK 来实现 RMI 服务,通讯细节这一块由 JDK 底层来实现,这就省了不少工作量。

引用服务

在没有注册中心,直连提供者的情况下,ReferenceConfig 解析出的 URL 的格式为:dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过 URL 的 dubbo:// 协议头识别,直接调用 DubboProtocol 的 refer() 方法,返回提供者引用。

在有注册中心,通过注册中心发现提供者地址的情况下,ReferenceConfig 解析出的 URL 的格式为: registry://registry-host/org.apache.dubbo.registry.RegistryService?refer=URL.encode("dubbo://consumer-host/com.foo.FooService?version=1.0.0")。

基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocol 的 refer() 方法,基于 refer 参数中的条件,查询提供者 URL,如: dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调用 DubboProtocol 的 refer() 方法,得到提供者引用。

然后 RegistryProtocol 将多个提供者引用,通过 Cluster 扩展点,伪装成单个提供者引用返回。

拦截服务

基于扩展点自适应机制,所有的 Protocol 扩展点都会自动套上 Wrapper 类。

基于 ProtocolFilterWrapper 类,将所有 Filter 组装成链,在链的最后一节调用真实的引用。

基于 ProtocolListenerWrapper 类,将所有 InvokerListener 和 ExporterListener 组装集合,在暴露和引用前后,进行回调。

包括监控在内,所有附加功能,全部通过 Filter 拦截实现。

消费服务

consume-service
上图是服务消费的主过程:

首先 ReferenceConfig 类的 init 方法调用 Protocol 的 refer 方法生成 Invoker 实例(如上图中的红色部分),这是服务消费的关键。接下来把 Invoker 转换为客户端需要的接口(如:HelloWorld)。

由于 Invoker 是 Dubbo 领域模型中非常重要的一个概念,很多设计思路都是向它靠拢。这就使得 Invoker 渗透在整个实现代码里,对于刚开始接触 Dubbo 的人,确实容易给搞混了。 下面我们用一个精简的图来说明最重要的两种 Invoker:服务提供 Invoker 和服务消费 Invoker:
provider-consumer-invoker
为了更好的解释上面这张图,我们结合服务消费和提供者的代码示例来进行说明:

服务消费者代码:

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,而该 Invoker 实现了真正的远程服务调用。

服务提供者代码:

public class DemoServiceImpl implements DemoService {

    public String sayHello(String name) throws RemoteException {
        return "Hello " + name;
    }
}

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

Dubbo协议

dubbo-protocol

  • Magic - Magic High & Magic Low (16 bits)
  • Identifies dubbo protocol with value: 0xdabb
  • Req/Res (1 bit)
    Identifies this is a request or response. Request - 1; Response - 0.
  • 2 Way (1 bit)
    Only useful when Req/Res is 1 (Request), expect for a return value from server or not. Set to 1 if need a return value from server.
  • Event (1 bit)
    Identifies an event message or not, for example, heartbeat event. Set to 1 if this is an event.
  • Serialization ID (5 bit)
  • Identifies serialization type: the value for fastjson is 6.
  • Status (8 bits)
    Only useful when Req/Res is 0 (Response), identifies the status of response
    20 - OK
    30 - CLIENT_TIMEOUT
    31 - SERVER_TIMEOUT
    40 - BAD_REQUEST
    50 - BAD_RESPONSE
    60 - SERVICE_NOT_FOUND
    70 - SERVICE_ERROR
    80 - SERVER_ERROR
    90 - CLIENT_ERROR
    100 - SERVER_THREADPOOL_EXHAUSTED_ERROR
  • Request ID (64 bits)
    Identifies an unique request. Numeric (long).
  • Data Length (32)
    Length of the content (the variable part) after serialization, counted by bytes. Numeric (integer).
  • Variable Part
    Dubbo version、Service name、Service version、Method name、Method parameter types、Method arguments、Attachments、Return value type、Return value

线程模型

dubbo-thread-model

  • Dispather: all, direct, message, execution, connection
  • ThreadPool: fixed, cached

文章说明

更多有价值的文章均收录于贝贝猫的文章目录

stun

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

创作声明: 本文基于下列所有参考内容进行创作,其中可能涉及复制、修改或者转换,图片均来自网络,如有侵权请联系我,我会第一时间进行删除。

参考内容

[1]《深入理解Apache Dubbo与实战》
[2] dubbo 官方文档

相关文章
|
7月前
|
Dubbo Java 应用服务中间件
启动速度提升 10 倍:Apache Dubbo 静态化方案深入解析
Apache Dubbo 集成了 GraalVM Native Image 后 ,Dubbo 应用能够做到毫秒级启动,启动速度降低了十倍、资源损耗降低了四倍,为降本增效提供了更多的想象空间。
启动速度提升 10 倍:Apache Dubbo 静态化方案深入解析
|
机器学习/深度学习 运维 Dubbo
全国首个政企采购云平台:政采云基于 Dubbo 的混合云跨网方案实践
全国首个政企采购云平台:政采云基于 Dubbo 的混合云跨网方案实践
全国首个政企采购云平台:政采云基于 Dubbo 的混合云跨网方案实践
|
Dubbo Cloud Native 网络协议
Dubbo Mesh 总体技术架构方案
本文将对 Dubbo Mesh 整体设计原则、部署架构与插件管控机制的规划做整体说明。
Dubbo Mesh 总体技术架构方案
|
负载均衡 Dubbo JavaScript
Dubbo服务治理之灰度发布方案(版本发布控制影响范围)
Dubbo服务治理之灰度发布方案(版本发布控制影响范围)
Dubbo服务治理之灰度发布方案(版本发布控制影响范围)
|
Dubbo Cloud Native 应用服务中间件
Dubbo/HSF在Service Mesh下的思考和方案
### 开头 Service Mesh这个“热”词是2016年9月被“造”出来,而今年2018年更是被称为service Mesh的关键之年,各家大公司都希望能在这个思潮下领先一步。今天我也分享阿里中间件在这方面的观点,思考和实践。考虑到有些人没了解过Dubbo(集团内以HSF为主)和Servicemesh,先简单介绍下这两个词。Dubbo应该是国内最受欢迎的远程服务框架,在Github上有超过
2163 0
|
Dubbo Cloud Native 应用服务中间件
|
Dubbo 应用服务中间件 Spring
线下Springboot+dubbo应用迁kubernetes方案
随着微服务应用架构的兴起,当前很多用户在开发测试生产上已经采用微服务的理念进行应用的架构设计及部署。常用的框架比如dubbo,springcloud等都已经在大规模进行使用了。当前kubernetes云原生应用的最佳部署平台,如何将线下的微服务应用迁移到kubernetes成为用户的一个难题,本文将以springboot+dubbo为例进行迁移的方案介绍。
5370 0
|
Dubbo Java 应用服务中间件
Spring Cloud与Dubbo共存方案总结
一、背景 假设有一个遗留的Dubbo系统,现在想改用Spring Cloud。 由于遗留Dubbo系统比较庞大,短期之内无法完成技术栈的迁移。因此需要“分步走”,即:初期实现两者共存,后期逐步绞杀Dubbo应用,最终实现技术栈的统一。
1233 0
|
5月前
|
负载均衡 Dubbo 应用服务中间件
微服务技术系列教程(31) - Dubbo-原理及负载均衡分析
微服务技术系列教程(31) - Dubbo-原理及负载均衡分析
55 0

热门文章

最新文章