核心概念

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 整体架构的核心要点

  1. 角色模型(5个核心角色)
    • Provider(服务提供者)
    • Consumer(服务消费者)
    • Registry(注册中心)
    • Monitor(监控中心)
    • Container(服务容器)
  2. 分层架构(10层设计)
    • 上层:Service、Config、Proxy(用户层)
    • 中层:Registry、Cluster、Monitor(服务治理)
    • 下层:Protocol、Exchange、Transport、Serialize(通信)
  3. 核心流程
    • 启动:Provider 注册 → Consumer 订阅 → 获取地址列表
    • 调用:代理拦截 → 负载均衡 → 容错重试 → 网络传输
    • 监控:定期上报调用统计
  4. 设计特点
    • 分层清晰:每层职责单一
    • 高扩展性:基于 SPI 机制
    • 服务治理:负载均衡、容错、限流、降级等

面试技巧:建议从角色模型分层架构调用流程的顺序回答,再补充扩展性和服务治理能力,体现对 Dubbo 架构的深入理解。