核心概念
Dubbo 是阿里开源的高性能 RPC 框架,采用分层架构设计,将服务调用、服务治理、协议传输等职责清晰分离。其核心目标是:让远程调用像本地调用一样简单,同时提供强大的服务治理能力。
整体架构特点:
- 分层清晰:10 层架构,职责明确
- 扩展性强:基于 SPI 机制,所有核心功能可插拔
- 协议无关:支持多种传输协议和序列化方式
核心架构图
1. 角色关系图
┌─────────────┐ ┌─────────────┐
│ Provider │ │ Consumer │
│ (服务提供者) │ │ (服务消费者) │
└──────┬──────┘ └──────┬──────┘
│ register │ subscribe
│ │
↓ ↓
┌─────────────────────────────────┐
│ Registry (注册中心) │
│ (Zookeeper/Nacos/...) │
└─────────────────────────────────┘
│
│ notify
↓
┌─────────────────┐
│ Consumer │
│ (获取提供者列表) │
└────────┬─────────┘
│
│ invoke (RPC调用)
↓
┌─────────────────┐
│ Provider │
│ (处理请求) │
└─────────────────┘
┌─────────────────┐
│ Monitor │
│ (监控中心) │
└─────────────────┘
↑ ↑
│ count │ count
│ │
Consumer Provider
2. 核心角色说明
| 角色 | 职责 | 典型实现 |
|---|---|---|
| Provider | 服务提供者,暴露服务 | 业务服务(订单、用户等) |
| Consumer | 服务消费者,调用远程服务 | 业务服务、API网关 |
| Registry | 注册中心,服务注册与发现 | Zookeeper、Nacos、Consul |
| Monitor | 监控中心,统计调用次数和时间 | Dubbo Admin、Prometheus |
| Container | 服务运行容器 | Spring容器、Main方法 |
3. 调用流程
// 服务提供者启动流程
1. Provider 启动 → 向 Registry 注册服务
dubbo://192.168.1.100:20880/com.example.UserService
// 服务消费者启动流程
2. Consumer 启动 → 向 Registry 订阅服务
3. Registry 返回 Provider 地址列表
4. Consumer 根据负载均衡策略选择 Provider
5. Consumer 发起 RPC 调用
// 运行时
6. Provider/Consumer 定期向 Monitor 上报调用统计
分层架构
Dubbo 框架设计为十层架构,从上到下依次为:
┌─────────────────────────────────────┐
│ Service (业务接口层) │ ← 用户代码
├─────────────────────────────────────┤
│ Config (配置层) │ ← @Service、@Reference
├─────────────────────────────────────┤
│ Proxy (代理层) │ ← 动态代理 (Javassist/JDK)
├─────────────────────────────────────┤
│ Registry (注册中心层) │ ← Zookeeper/Nacos
├─────────────────────────────────────┤
│ Cluster (集群容错层) │ ← Failover/Failfast/Failsafe
├─────────────────────────────────────┤
│ Monitor (监控层) │ ← 调用统计
├─────────────────────────────────────┤
│ Protocol (远程调用层) │ ← Dubbo/HTTP/gRPC
├─────────────────────────────────────┤
│ Exchange (信息交换层) │ ← Request/Response
├─────────────────────────────────────┤
│ Transport (网络传输层) │ ← Netty/Mina
├─────────────────────────────────────┤
│ Serialize (序列化层) │ ← Hessian2/Protobuf/Kryo
└─────────────────────────────────────┘
各层详解
1. Service(业务接口层)
// 用户定义的服务接口和实现
public interface UserService {
User getUser(Long userId);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public User getUser(Long userId) {
return userMapper.selectById(userId);
}
}
2. Config(配置层)
// 配置管理:@Service、@Reference、application.yml
@Service(
timeout = 3000,
retries = 2,
loadbalance = "random"
)
public class UserServiceImpl implements UserService { }
@Reference(timeout = 5000)
private OrderService orderService;
3. Proxy(代理层)
// 为 Consumer 生成服务代理,屏蔽远程调用细节
UserService proxy = ProxyFactory.getProxy(UserService.class);
// 调用代理方法 → 触发远程调用
proxy.getUser(123L);
// 底层使用 Javassist 或 JDK 动态代理
4. Registry(注册中心层)
// 服务注册与发现
registry.register(URL.valueOf("dubbo://192.168.1.100:20880/UserService"));
List<URL> urls = registry.lookup("com.example.UserService");
5. Cluster(集群容错层)
// 负载均衡、集群容错、路由
@Reference(
loadbalance = "random", // 随机负载均衡
cluster = "failover", // 失败自动切换
retries = 2 // 重试2次
)
private UserService userService;
6. Monitor(监控层)
// 调用统计上报
monitor.collect(new Statistics(
service = "UserService",
method = "getUser",
count = 1,
elapsed = 50 // 耗时50ms
));
7. Protocol(远程调用层)
// 封装 RPC 调用,支持多协议
Exporter exporter = protocol.export(invoker); // 服务暴露
Result result = protocol.refer(UserService.class, url).invoke(invocation); // 服务引用
8. Exchange(信息交换层)
// 封装请求/响应模式,支持同步/异步
Request request = new Request();
request.setData(invocation);
Future<Response> future = channel.request(request);
9. Transport(网络传输层)
// 基于 Netty 进行网络通信
Server server = Transporters.bind("dubbo://0.0.0.0:20880");
Client client = Transporters.connect("dubbo://192.168.1.100:20880");
10. Serialize(序列化层)
// 数据序列化/反序列化
byte[] bytes = serialization.serialize(object);
Object obj = serialization.deserialize(bytes);
完整调用链路
以消费者调用 userService.getUser(123L) 为例:
// 1. 用户调用代理对象
userService.getUser(123L);
// 2. Proxy 层:拦截方法调用
InvokerInvocationHandler.invoke()
→ 构造 RpcInvocation
// 3. Cluster 层:负载均衡选择一个 Provider
LoadBalance.select(invokers)
→ 选出目标 Invoker
// 4. 集群容错:失败重试
FailoverClusterInvoker.invoke()
→ 失败则切换到其他 Provider
// 5. Filter 链:执行过滤器(监控、日志、限流等)
ConsumerContextFilter → MonitorFilter → ...
// 6. Protocol 层:构造 RPC 请求
DubboProtocol.refer()
→ 创建 DubboInvoker
// 7. Exchange 层:发送请求
HeaderExchangeChannel.request()
→ 生成 Request 对象
// 8. Transport 层:Netty 发送数据
NettyChannel.send()
→ 写入 Socket
// 9. Serialize 层:序列化数据
Hessian2Serialization.serialize()
→ 转为字节流
// ===== 网络传输 =====
// 10. Provider 接收请求(反向流程)
Netty Handler → Decode → DubboProtocol.reply()
→ 调用真实服务 → 返回结果
// 11. Consumer 接收响应
Netty Handler → Decode → 反序列化
→ 返回给调用方
核心特性
1. SPI 扩展机制
// Dubbo SPI 示例
@SPI("random")
public interface LoadBalance {
<T> Invoker<T> select(List<Invoker<T>> invokers, Invocation invocation);
}
// 扩展实现
public class CustomLoadBalance implements LoadBalance {
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, Invocation invocation) {
// 自定义负载均衡逻辑
}
}
// META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance
// custom=com.example.CustomLoadBalance
2. 服务治理能力
// 服务降级
@Reference(mock = "return null")
private UserService userService;
// 服务限流
@Service(executes = 10) // 最多10个并发请求
public class UserServiceImpl implements UserService { }
// 服务分组
@Service(group = "v1")
public class UserServiceV1Impl implements UserService { }
@Service(group = "v2")
public class UserServiceV2Impl implements UserService { }
@Reference(group = "v2")
private UserService userService; // 只调用 v2 版本
3. 多协议支持
// 同时暴露多个协议
@Service(protocol = {"dubbo", "rest"})
public class UserServiceImpl implements UserService {
// 可以通过 Dubbo 协议调用(内部)
// 也可以通过 HTTP REST 调用(对外)
}
// 配置文件
dubbo:
protocols:
- name: dubbo
port: 20880
- name: rest
port: 8080
答题总结
Dubbo 整体架构的核心要点:
- 角色模型(5个核心角色):
- Provider(服务提供者)
- Consumer(服务消费者)
- Registry(注册中心)
- Monitor(监控中心)
- Container(服务容器)
- 分层架构(10层设计):
- 上层:Service、Config、Proxy(用户层)
- 中层:Registry、Cluster、Monitor(服务治理)
- 下层:Protocol、Exchange、Transport、Serialize(通信)
- 核心流程:
- 启动:Provider 注册 → Consumer 订阅 → 获取地址列表
- 调用:代理拦截 → 负载均衡 → 容错重试 → 网络传输
- 监控:定期上报调用统计
- 设计特点:
- 分层清晰:每层职责单一
- 高扩展性:基于 SPI 机制
- 服务治理:负载均衡、容错、限流、降级等
面试技巧:建议从角色模型 → 分层架构 → 调用流程的顺序回答,再补充扩展性和服务治理能力,体现对 Dubbo 架构的深入理解。