分布式架构与Dubbo简介

分布式架构

随着互联网应用的快速发展,传统的单体架构已经难以满足日益增长的业务需求。分布式架构应运而生,它将一个大型的应用系统拆分成多个独立的子系统或服务,这些服务可以独立开发、部署和运行,通过网络进行通信和协作。

Dubbo是阿里巴巴开源的一个高性能、轻量级的Java RPC(Remote Procedure Call,远程过程调用)框架,它提供了服务治理、负载均衡、容错机制等一系列功能,帮助开发者构建分布式应用系统。

Dubbo的核心组件

参考架构图:

img

  • Provider:服务提供者,负责提供具体的服务实现,并将服务注册到注册中心。
  • Consumer:服务消费者,从注册中心获取服务提供者的信息,并调用这些服务。
  • Registry:注册中心,负责服务的注册和发现,常见的注册中心有ZooKeeper、Nacos等。
  • Monitor:监控中心,用于监控服务的调用情况,如调用次数、调用时间等。

Dubbo的特性

  • 高性能:Dubbo采用了高性能的网络通信框架Netty,支持多种序列化协议,如Hessian、JSON等,可以满足不同场景下的性能需求。
  • 服务治理:Dubbo提供了丰富的服务治理功能,如服务注册、发现、负载均衡、容错机制等,可以保证服务的高可用性和稳定性。
  • 扩展性:Dubbo的架构设计非常灵活,开发者可以通过扩展Dubbo的SPI(Service Provider Interface)机制,实现自定义的功能。

Dubbo的使用场景

  • 分布式系统:Dubbo可以帮助开发者构建分布式系统,实现服务的解耦和复用。
  • 微服务架构:Dubbo是微服务架构中的一个重要组件,可以作为微服务之间的通信框架。

Dubbo分层架构

Dubbo可以按照功能分为Bussiness(业务层)、RPC层和Remoting层;也可以按照开发与扩展方式分为API层和SPI层。进一步细分的话则可以分为十层,如下图所示:

image-20250224195014968

每一层的职责,参照官方文档,如下:

  • Service 业务层:即实际开发时的业务逻辑层;
  • Config 配置层:对外配置接口,以 ServiceConfig, ReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类;
  • Proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory。这里的Stub和Skeleton指的实际上就是客户端和服务端的代理对象。客户端使用代理对象发起远程调用,服务端使用代理对象接收调用请求并返回结果;
  • Registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService
  • Cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,负责选取具体调用的节点,处理特殊的调用要求和负责远程调用失败的容错措施。以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance
  • Monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService
  • Protocol 远程调用层:封装 RPC 调用,管理Invoker。以 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调用过程概览

服务暴露过程

服务暴露只涉及到服务提供者和注册中心,整个流程可以参考下图:

image-20250224203605618

  1. 初始化服务:Provider 首先需要定义服务接口,并实现该接口。
  2. Proxy:Dubbo 使用动态代理技术生成服务接口的代理类Proxy,它根据具体的协议 Protocol 将需要暴露出去的接口封装成 Invoker。
  3. Invoker:Invoker 是服务的抽象表示,它是一个可执行体,负责调用具体的服务实现。
  4. Export:将 Invoker 导出为服务,使其可以被远程访问。这一步会将服务绑定到具体的协议和端口上。
  5. 注册服务:将服务信息注册到注册中心,以便服务消费者可以发现服务。
消费过程

包含了刚刚的暴露过程和消费过程的完整流程图如下,从右上角Consumer初始化服务开始:

image-20250224204502461

消费者发出网络请求的过程:

  1. 初始化服务:Consumer 首先需要定义服务接口,并使用 Dubbo 提供的 API 来引用该服务。
  2. Proxy:动态代理生成服务接口的代理类,将调用转发到 Invoker。
  3. Invoker:Invoker 是服务的抽象表示,负责调用远程服务。
  4. Cluster:集群管理,用于处理多个服务提供者的情况。如果一个服务有多个提供者,Dubbo 会使用集群管理来决定请求应该发送到哪个提供者。
  5. Directory:从注册中心获取服务提供者的地址列表。
  6. Router:路由管理,根据路由规则,比如某个接口只能调用某个节点,过滤掉一些Invoker。
  7. LoadBalance:负载均衡,用于在多个服务提供者之间分配请求。
  8. Filter:在服务调用过程中可以加入过滤器,用于处理请求和响应的预处理和后处理。
  9. Invoker:通过 Invoker 进行服务调用。
  10. Client:客户端如Netty,用于发起远程服务调用。
  11. Codec:编解码器,根据指定的协议构造网络传输数据。
  12. Serialization:序列化服务请求。

提供者收到网络请求后:

  1. Serialization:反序列化服务请求。
  2. Codec:根据指定的协议解码网络传输数据。(这两条没有体现在图中)
  3. ThreadPool:当Server接收到请求后,会将请求交给线程池处理。线程池负责管理线程资源,通过复用线程来提高系统性能,减少线程创建和销毁的开销。
  4. Server:用于监听端口、接收请求和发送响应。
  5. Exporter:将服务接口绑定到具体的协议和端口上,使其可以被远程访问。负责接收来自Server的请求,并将其转发给相应的Invoker进行处理。
  6. Filter:在请求和响应的处理过程中进行拦截和处理。
  7. Invoker:负责调用服务提供者的具体实现,并返回结果。

__END__