Dubbo 的整体架构是怎样的?


面试考察点

  1. 全局视角:面试官不仅仅想知道你能不能画出那张经典的架构图,更是想看你有没有 "上帝视角"——能不能从整体上理解一个 RPC 框架的设计思路,而不是只会 @Reference 调用一下就完事了。

  2. 角色划分理解:考察你是否清楚 Provider、Consumer、Registry、Monitor 这几个核心角色的职责边界,以及它们之间的协作关系。说白了,Dubbo 的设计哲学就藏在这些角色的拆分里。

  3. 架构设计思维:面试官还想知道你是否理解 Dubbo 为什么要这么设计,比如为什么要有注册中心、为什么要用 SPI 机制、为什么要把协议和序列化做成可插拔的。这些才是真正体现架构思维的地方。

核心答案

Dubbo 的整体架构可以用 5 个核心角色 + 分层设计 来概括。

先说 5 个核心角色:

角色 职责 一句话理解
Provider 暴露服务,注册到注册中心 服务的提供方
Consumer 订阅服务,从注册中心获取地址 服务的消费方
Registry 服务注册与发现 电话簿,谁提供了什么服务都在这查
Monitor 统计服务调用数据 记录谁调了谁,调了多少次,耗时多久
Container 服务运行容器 负责启动、加载、运行 Provider

再说分层设计,Dubbo 把自身的功能拆成了三大层十小层,每一层只做一件事,层与层之间通过 SPI 机制解耦。这种设计让 Dubbo 极其灵活,比如你想换一个注册中心(从 ZooKeeper 换成 Nacos),只需要改配置就行,其他层完全不受影响。

深度解析

一、整体架构图

先看这张经典的架构图,Dubbo 官方文档里也有,但我会加上我自己的理解来讲:

整体的工作流程可以这样理解:

  • 注册阶段Provider 启动后,把自己提供的服务信息(接口名、版本号、IP 地址、端口等)注册到 Registry。就好比一家餐厅开业了,去美团上登记一下自己的店名和地址。

  • 发现阶段Consumer 启动后,向 Registry 订阅自己需要的服务。Registry 会把可用的 Provider 地址列表推送给 Consumer。这就像你在美团上搜 "火锅店",平台把附近的店都列出来给你。

  • 调用阶段Consumer 拿到地址列表后,根据负载均衡策略(随机、轮询、权重等)选一个 Provider,直接发起 RPC 调用。注意,调用过程不经过注册中心,是点对点的,注册中心挂了也不影响已经发现的服务的调用。

  • 监控阶段ConsumerProvider 会异步地把调用次数、耗时等信息上报给 Monitor,用于运维分析和性能优化。

这里面有个非常关键的点:注册中心只负责服务发现,不负责服务调用。这意味着注册中心即使挂了,消费者本地已经缓存了提供者列表,照样能调用。这个设计保证了 Dubbo 的高可用性。我之前有次线上 ZooKeeper 集群抖动,但服务调用完全没受影响,靠的就是这个本地缓存机制。

二、Dubbo 的分层架构

Dubbo 内部采用了分层架构设计,整体分为三大层:

上面这张图展示了 Dubbo 的十层架构,从上到下依次是:

  • Business 层:就是你自己写的业务代码,Service 接口和实现类。Dubbo 不关心你这层写什么,它只负责把你的服务暴露出去或远程调用过来。

  • RPC 层:这是 Dubbo 的核心所在,里面又细分了 6 层。每一层都可以单独替换,互不影响:

    • Config 层负责解析你写的 @DubboService@DubboReference 这些注解或 XML 配置
    • Proxy 层为你生成代理类,让你像调本地方法一样调用远程服务,完全透明
    • Registry 层负责和注册中心打交道,注册、订阅、通知
    • Cluster 层是消费者端的 "大脑",负责负载均衡、容错策略、服务路由
    • Monitor 层负责统计调用数据
    • Protocol 层封装整个 RPC 调用过程,是 Dubbo 的协议核心
  • Remoting 层:这层负责底层的网络通信。Transport 层抽象了 Netty、Mina 等网络框架;Exchange 层在此基础上封装了请求-响应模型;Serialize 层处理数据的序列化和反序列化。

你可能觉得十层太多了,记不住。说实话,你不需要把十层都背下来,但至少要记住三大层的划分,以及每个大层里最核心的那几个。面试的时候能把 ProxyRegistryClusterProtocol 这几个关键层的作用说清楚,基本就够用了。

三、SPI 机制——Dubbo 灵活性的根基

说到 Dubbo 的架构,就不得不提它的 SPI(Service Provider Interface)机制。这玩意儿是 Dubbo 架构的灵魂。

Java 自己也有 SPI 机制(java.util.ServiceLoader),但 Dubbo 做了增强,自己搞了一套:

特性 Java SPI Dubbo SPI
配置方式 META-INF/services/ META-INF/dubbo/
按需加载 不支持,全部加载 支持,按 key 加载
依赖注入 不支持 支持自动注入
AOP 增强 不支持 支持 Wrapper 包装
自动激活 不支持 @Activate 注解支持

Dubbo 的 SPI 机制使得 ProtocolSerializationTransportRegistry 等所有核心组件都可以灵活替换。这也是为什么 Dubbo 能同时支持 Dubbo 协议、REST 协议、gRPC 协议,能同时对接 ZooKeeper、Nacos、Consul 等注册中心——全部都是 SPI 在背后支撑。

四、服务调用全链路

从 Consumer 发起调用到 Provider 返回结果,完整的链路是这样的:

用一个简单的代码例子来感受一下:

// Provider 端 —— 暴露服务
@DubboService(version = "1.0.0")
public class UserServiceImpl implements UserService {
    @Override
    public User getUserById(Long id) {
        return userDao.selectById(id);
    }
}

// Consumer 端 —— 调用远程服务
@RestController
public class OrderController {

    @DubboReference(version = "1.0.0")
    private UserService userService;

    @GetMapping("/order/{userId}")
    public User getUser(@PathVariable Long userId) {
        // 看起来像本地调用,实际经过了 Proxy → Cluster → Protocol → 网络 → Provider 的完整链路
        return userService.getUserById(userId);
    }
}

这段代码里,OrderController 调用 userService.getUserById() 看起来就是一次普通的方法调用,但背后 Dubbo 的 Proxy 层帮你生成了代理对象,然后经过 Filter 链、Cluster 层的负载均衡选择一个 Provider,再通过 Protocol 层把请求序列化后发到网络上,Provider 端反序列化后执行真正的业务逻辑,最后把结果再序列化回来。

整个过程对你来说是完全透明的,这就是 RPC 框架的核心价值。

面试高频追问

  1. Dubbo 的注册中心挂了还能正常调用吗?

    可以。Consumer 本地缓存了 Provider 的地址列表,注册中心挂了只是无法感知新的服务上下线,但已经发现的服务的调用完全不受影响。这也是为什么我前面说注册中心只负责 "发现",不负责 "调用"。

  2. Dubbo 支持哪些注册中心?生产环境怎么选?

    支持 ZooKeeper、Nacos、Redis、Simple 等。现在主流是 Nacos,轻量、好运维、还支持配置中心。ZooKeeper 偏重,但稳定性经过了阿里双十一验证。新的项目我一般推荐 Nacos。

  3. Dubbo 和 Spring Cloud 有什么区别?

    这道题值得单独写一篇。简单说,Dubbo 是 RPC 框架,Spring Cloud 是微服务全家桶。Dubbo 性能更好(自定义二进制协议 + 高效序列化),Spring Cloud 生态更全(配置中心、网关、熔断、链路追踪全有)。不过现在 Dubbo 3.x 也在补齐生态,两者也在融合(Dubbo 已经可以接入 Spring Cloud 的注册中心了)。

  4. Dubbo 的 SPI 和 Java 的 SPI 有什么区别?

    前面表格已经对比过了。核心区别是 Dubbo SPI 支持按需加载、依赖注入、AOP 包装和自动激活,比 Java SPI 强大得多。Dubbo 的整个架构扩展性就是建立在 SPI 之上的。

常见面试变体

  • "Dubbo 的核心组件有哪些?各自的作用是什么?"
  • "画一下 Dubbo 的架构图,说说各个角色的交互流程"
  • "Dubbo 一次完整的 RPC 调用流程是什么样的?"
  • "Dubbo 为什么采用分层架构?有什么好处?"

记忆口诀

五大角色Provider 提供服务,Consumer 消费服务,Registry 管地址,Monitor 管统计,Container 管启动。

三层架构:Business 写业务,RPC 管调度,Remoting 管通信。

调用链路:业务 → 代理 → 过滤 → 集群(负载均衡)→ 协议 → 网络 → 协议 → 过滤 → 代理 → 业务。

总结

Dubbo 的架构设计可以用 "五大角色 + 分层解耦 + SPI 扩展" 来概括。理解了注册中心只负责服务发现不负责服务调用、Consumer 本地缓存保证高可用、SPI 机制让每一层都可替换这三点,面试官问到 Dubbo 架构你就基本稳了。