Dubbo 底层原理系列(一):架构概述
2020-07-08·5 分钟阅读
前言
Apache Dubbo 是一款高性能 Java RPC 框架,由阿里巴巴开源并贡献给 Apache 基金会。本文将深入解析 Dubbo 的整体架构设计。
技术亮点
| 技术点 | 难度 | 面试价值 | 本文覆盖 |
|---|---|---|---|
| 分层架构 | ⭐⭐⭐ | 高频考点 | ✅ |
| 核心组件 | ⭐⭐⭐ | 高频考点 | ✅ |
| 工作流程 | ⭐⭐⭐⭐ | 进阶考点 | ✅ |
| SPI 机制 | ⭐⭐⭐⭐ | 高频考点 | ✅ |
面试考点
- Dubbo 的整体架构是怎样的?
- Dubbo 有哪些核心组件?
- Dubbo 的一次完整调用流程是怎样的?
- Dubbo 与 Spring Cloud 有什么区别?
Dubbo 简介
什么是 Dubbo
┌─────────────────────────────────────────────────────────────────────────┐
│ Dubbo 简介 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Apache Dubbo 是一款高性能、轻量级的 Java RPC 框架: │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 核心能力: │ │
│ │ • 面向接口代理的高性能 RPC 调用 │ │
│ │ • 智能负载均衡 │ │
│ │ • 自动服务注册与发现 │ │
│ │ • 高度可扩展能力 │ │
│ │ • 运行期流量调度 │ │
│ │ • 可视化的服务治理与运维 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 发展历程: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 2008 年:阿里巴巴内部开始使用 │ │
│ │ 2011 年:开源发布 1.0 版本 │ │
│ │ 2014 年:停止维护,最后版本 2.4.11 │ │
│ │ 2017 年:重启维护,发布 2.5.4 │ │
│ │ 2018 年:进入 Apache 孵化器 │ │
│ │ 2019 年:成为 Apache 顶级项目 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
分层架构
架构图
┌─────────────────────────────────────────────────────────────────────────┐
│ Dubbo 分层架构 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 业务层 (Business) │ │ │
│ │ │ Service / ServiceImpl │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ RPC 层 (RPC) │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Proxy │ │ Invoker │ │ Protocol │ │ │ │
│ │ │ │ 服务代理 │ │ 调用抽象 │ │ 协议实现 │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 远程调用层 (Remoting) │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Exchange │ │ Transport │ │ Serialize │ │ │ │
│ │ │ │ 信息交换 │ │ 网络传输 │ │ 序列化 │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 服务治理层 (Governance) │ │ │
│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐│ │ │
│ │ │ │Config │ │Registry│ │Cluster │ │Monitor │ │Router ││ │ │
│ │ │ │配置 │ │注册 │ │集群 │ │监控 │ │路由 ││ │ │
│ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘│ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
各层职责
┌─────────────────────────────────────────────────────────────────────────┐
│ 各层职责 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 服务接口层 (Service) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • 业务接口定义 │ │
│ │ • 业务实现类 │ │
│ │ • 用户可见的 API 层 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 配置层 (Config) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • ServiceConfig:服务暴露配置 │ │
│ │ • ReferenceConfig:服务引用配置 │ │
│ │ • ApplicationConfig:应用配置 │ │
│ │ • RegistryConfig:注册中心配置 │ │
│ │ • ProtocolConfig:协议配置 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 3. 服务注册层 (Registry) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • 服务注册与发现 │ │
│ │ • 支持多种注册中心(Zookeeper、Nacos、Redis 等) │ │
│ │ • 订阅与通知机制 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 4. 集群层 (Cluster) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • 负载均衡:Random、RoundRobin、LeastActive 等 │ │
│ │ • 集群容错:Failover、Failfast、Failsafe 等 │ │
│ │ • 服务路由:条件路由、脚本路由 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 5. 协议层 (Protocol) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • Invoker 封装和导出 │ │
│ │ • 服务发布和引用 │ │
│ │ • 支持多种协议:dubbo、rmi、hessian、http 等 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
核心组件
组件关系图
┌─────────────────────────────────────────────────────────────────────────┐
│ 核心组件关系图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Provider │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ ServiceConfig ──► ServiceBean ──► Protocol.export() │ │ │
│ │ │ │ │ │ │ │
│ │ │ ▼ ▼ │ │ │
│ │ │ RegistryProtocol Invoker (服务提供者) │ │ │
│ │ │ │ │ │ │
│ │ │ ▼ │ │ │
│ │ │ Registry.register() ──► Zookeeper │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Registry │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ Zookeeper / Nacos │ │ │
│ │ │ /dubbo/com.xxx.Service/providers │ │ │
│ │ │ /dubbo/com.xxx.Service/consumers │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Consumer │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ ReferenceConfig ──► ReferenceBean ──► ProxyFactory │ │ │
│ │ │ │ │ │ │ │ │
│ │ │ ▼ ▼ ▼ │ │ │
│ │ │ RegistryProtocol Cluster Proxy (代理对象) │ │ │
│ │ │ │ │ │ │ │
│ │ │ ▼ ▼ │ │ │
│ │ │ Registry.subscribe() Directory │ │ │
│ │ │ │ │ │ │ │
│ │ │ ▼ ▼ │ │ │
│ │ │ 获取服务列表 Router ──► LoadBalance │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
核心概念
┌─────────────────────────────────────────────────────────────────────────┐
│ 核心概念 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Invoker │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • Dubbo 核心模型,代表一个可执行体 │ │
│ │ • 服务端:Invoker 封装服务实现 │ │
│ │ • 客户端:Invoker 封装远程调用逻辑 │ │
│ │ │ │
│ │ interface Invoker { │ │
│ │ Class getInterface(); │ │
│ │ Result invoke(Invocation inv) throws RpcException; │ │
│ │ } │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 2. URL │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • Dubbo 的配置总线,贯穿整个框架 │ │
│ │ • 格式:protocol://host:port/path?key=value&key=value │ │
│ │ │ │
│ │ 示例: │ │
│ │ dubbo://192.168.1.1:20880/com.xxx.UserService? │ │
│ │ timeout=3000&retries=2&loadbalance=random │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 3. Protocol │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • 服务发布和引用的入口 │ │
│ │ • export():暴露服务 │ │
│ │ • refer():引用服务 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 4. Directory │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ • 服务目录,维护可用的 Invoker 列表 │ │
│ │ • 动态更新服务列表 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
调用流程
服务暴露流程
┌─────────────────────────────────────────────────────────────────────────┐
│ 服务暴露流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. ServiceConfig.export() │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 2. 创建 Invoker (ProxyFactory.getInvoker) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 3. Protocol.export(invoker) │ │
│ │ │ │ │
│ │ ├──► DubboProtocol:启动 Netty Server │ │
│ │ │ │ │
│ │ └──► RegistryProtocol:注册到注册中心 │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Registry.register(url) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Zookeeper.create(path, url) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 最终在 Zookeeper 创建的节点: │
│ /dubbo/com.xxx.UserService/providers/ │
│ dubbo://192.168.1.1:20880/com.xxx.UserService?... │
│ │
└─────────────────────────────────────────────────────────────────────────┘
服务引用流程
┌─────────────────────────────────────────────────────────────────────────┐
│ 服务引用流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. ReferenceConfig.get() │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 2. Protocol.refer(url) │ │
│ │ │ │ │
│ │ ├──► RegistryProtocol:从注册中心获取服务列表 │ │
│ │ │ │ │ │
│ │ │ ▼ │ │
│ │ │ Registry.subscribe(url, listener) │ │
│ │ │ │ │ │
│ │ │ ▼ │ │
│ │ │ Directory.list() ──► Invoker 列表 │ │
│ │ │ │ │
│ │ └──► Cluster.join(directory) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 创建 Cluster Invoker │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 3. ProxyFactory.getProxy(clusterInvoker) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 返回代理对象 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
一次 RPC 调用流程
┌─────────────────────────────────────────────────────────────────────────┐
│ 一次 RPC 调用流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Consumer Provider │
│ ┌────────────────────┐ ┌────────────────────┐│
│ │ │ │ ││
│ │ 1. 代理对象调用 │ │ ││
│ │ │ │ │ ││
│ │ ▼ │ │ ││
│ │ 2. Cluster │ │ ││
│ │ Invoker.invoke() │ │ ││
│ │ │ │ │ ││
│ │ ▼ │ │ ││
│ │ 3. Router 过滤 │ │ ││
│ │ │ │ │ ││
│ │ ▼ │ │ ││
│ │ 4. LoadBalance │ │ ││
│ │ 选择 Invoker │ │ ││
│ │ │ │ │ ││
│ │ ▼ │ │ ││
│ │ 5. Filter 链 │ │ ││
│ │ │ │ │ ││
│ │ ▼ │ Netty 请求 │ ││
│ │ 6. DubboInvoker │──────────────────────────►│ 7. Netty Handler ││
│ │ │ │ │ ││
│ │ │ │ ▼ ││
│ │ │ │ 8. 线程池分发 ││
│ │ │ │ │ ││
│ │ │ │ ▼ ││
│ │ │ │ 9. 解码请求 ││
│ │ │ │ │ ││
│ │ │ │ ▼ ││
│ │ │ │ 10. 反射调用 ││
│ │ │ │ 服务实现 ││
│ │ │ │ │ ││
│ │ │ Netty 响应 │ ▼ ││
│ │ 11. 接收响应 │◄──────────────────────────│ 11. 编码响应 ││
│ │ │ │ │ ││
│ │ ▼ │ │ ││
│ │ 12. 返回结果 │ │ ││
│ │ │ │ ││
│ └────────────────────┘ └────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────┘
Dubbo vs Spring Cloud
┌─────────────────────────────────────────────────────────────────────────┐
│ Dubbo vs Spring Cloud │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 对比项 Dubbo Spring Cloud │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ 定位 RPC 框架 微服务全家桶 │ │
│ │ 通信方式 Netty TCP HTTP/REST │ │
│ │ 性能 高(二进制协议) 中(HTTP 协议) │ │
│ │ 服务治理 内置 需要集成各组件 │ │
│ │ 注册中心 Zookeeper/Nacos Eureka/Consul/Nacos │ │
│ │ 负载均衡 客户端 客户端/服务端 │ │
│ │ 熔断降级 Sentinel Hystrix/Resilience4j │ │
│ │ 配置中心 内置/Nacos Spring Cloud Config │ │
│ │ 网关 无内置 Spring Cloud Gateway │ │
│ │ 学习成本 较低 较高 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 选择建议: │
│ • 追求高性能、服务间调用频繁:选择 Dubbo │
│ • 需要完整的微服务解决方案:选择 Spring Cloud │
│ • 团队技术栈以 Java 为主:Dubbo 更友好 │
│ • 需要多语言支持:Spring Cloud(HTTP 协议通用) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
总结
本文介绍了 Dubbo 的整体架构:
| 概念 | 说明 |
|---|---|
| 分层架构 | 业务层、RPC 层、远程调用层、服务治理层 |
| 核心组件 | Invoker、URL、Protocol、Directory |
| 调用流程 | 服务暴露、服务引用、RPC 调用 |
参考资料
下一章预告
下一章将深入解析 SPI 机制,包括:
- ExtensionLoader 原理
- 自适应扩展
- 扩展点加载机制
相关文章
Dubbo 底层原理系列(七):集群容错
2020-09-03·5 分钟阅读
深入解析 Dubbo 集群容错原理,包括 Failover、Failfast、Failsafe、Failback、Forking、Broadcast 等容错模式。
Dubbo 底层原理系列(六):负载均衡
2020-08-25·5 分钟阅读
深入解析 Dubbo 负载均衡原理,包括 Random、RoundRobin、LeastActive、ConsistentHash 策略的实现细节。
Dubbo 底层原理系列(四):服务引用
2020-08-03·5 分钟阅读
深入解析 Dubbo 服务引用原理,包括服务引用流程、代理对象创建、Directory 与 Cluster Invoker 构建。