Dubbo 原理

本文最后更新于:2024年3月18日 凌晨

Dubbo 原理

RPC 原理

image-20211209100424265
  • 一次完整的RPC调用流程(同步调用)如下:
    1. 服务消费方(client)调用以本地调用方式调用服务。
    2. client stub 接收到调用后负责将方法,参数等组装成能够进行网络传输的消息体。
    3. client stub 找到服务地址,并将消息发送到服务端。
    4. server stub 收到消息后进行解码。
    5. server stub 根据解码结果调用本地的服务。
    6. 本地服务执行并将结果返回给 server stub
    7. server stub 将返回结果打包成消息并发送至消费方。
    8. client stub 接收到消息,并进行解码。
    9. 服务消费方得到最终结果。
  • RPC框架的目标就是要将2~8步封装起来,这些细节对用户来说是透明的。

Netty 通信原理

  • Netty 是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端,它极大地简化并简化了TCP和UDP套接字服务器等网络编程。

BIO(阻塞式IO)

image-20211209114705251

NIO(非阻塞式IO)

image-20211209120321671
  • Selector 一般称为选择器,也可以翻译为多路复用器。
  • Connect (连接就绪),Accept (接受就绪),Read(读就绪),Write(写就绪)

Dubbo 框架设计

img

  • config 配置层:对外配置接口,以 ServiceConfig, ReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类。
  • proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory
  • registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService
  • cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance
  • monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService
  • protocol 远程调用层:封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter
  • exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
  • transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec
  • serialize 数据序列化层:可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool

标签解析

  • 初始化标签解析器,解析dubbo标签并封装到对应的Config类中。
在这里插入图片描述

服务暴露

  1. 在ServiceBean解析完成并触发ContextRefreshEvent方法。
  2. 调用export()方法,暴露服务。
  3. doExportUrls()方法遍历配置的RPC协议与端口号并各自调用其doExportUrlsFor1Protocol()方法。
  4. 通过getInvoker()方法获取提供的方法代理对象。
  5. 将获取到的invoker代入protocol.export(invoker)方法。
  6. 启动Netty服务器openServer()
  7. 注册服务到注册中心ProviderConsumerRegTable.registerProvider()
在这里插入图片描述

服务引用

  1. 在ReferenceBean解析完成并实现FactoryBean.getObject()方法。
  2. 调用ReferenceConfig的get()方法,如果对象为空,调用init()方法初始化。
  3. 通过ProxyFactory对象的createProxy()方法创建代理对象。
  4. Protocol.refer()引用远程服务。
  5. DubboProtocol.getClients()获取客户端,并调用Exchangers.connect()方法进行连接。
  6. 注册服务到注册中心ProviderConsumerRegTable.registerConsumer()
  7. 调用RegistryProtocol.doRefer()订阅服务。
  8. 返回invoker代理对象。

在这里插入图片描述

服务调用

在这里插入图片描述


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!