Dubbo 架构与原理
Dubbo 架构与原理
Section titled “Dubbo 架构与原理”Dubbo 整体架构
Section titled “Dubbo 整体架构”┌─────────────────────────────────────────────────────────────────────┐│ Dubbo 架构 │├─────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ Service │ │ Config │ │ Proxy │ ││ │ Provider │ │ Layer │ │ Layer │ ││ └─────────────┘ └─────────────┘ └─────────────┘ ││ │ │ │ ││ └───────────────────┼───────────────────┘ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Registry │ ││ │ (注册中心层) │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ Cluster │ │ Monitor │ │ Protocol │ ││ │ Layer │ │ Layer │ │ Layer │ ││ └─────────────┘ └─────────────┘ └─────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Exchange │ ││ │ (信息交换层) │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Transport │ ││ │ (网络传输层) │ ││ └─────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────┘核心组件说明
Section titled “核心组件说明”| 层级 | 组件 | 职责 |
|---|---|---|
| Business | Service | 业务层,即开发者实现的接口 |
| RPC | Config | 配置层,暴露/引用服务的配置 |
| RPC | Proxy | 代理层,生成 Stub 代理 |
| RPC | Registry | 注册中心,服务注册与发现 |
| RPC | Cluster | 集群层,负载均衡、容错 |
| RPC | Monitor | 监控层,统计调用次数、耗时 |
| RPC | Protocol | 协议层,RPC 调用的协议封装 |
| Remoting | Exchange | 信息交换层,请求响应模型 |
| Remoting | Transport | 传输层,NIO、Netty、Mina |
服务注册与发现
Section titled “服务注册与发现”服务提供者启动
Section titled “服务提供者启动”// 1. 配置服务@DubboService(version = "1.0.0", group = "prod")public class UserServiceImpl implements UserService { @Override public User getUserById(Long id) { return userDao.selectById(id); }}<!-- 2. 配置文件 --><dubbo:application name="user-service" /><dubbo:registry address="zookeeper://127.0.0.1:2181" /><dubbo:protocol name="dubbo" port="20880" /><dubbo:service interface="com.example.UserService" ref="userService" />服务消费者引用
Section titled “服务消费者引用”// 1. 引用远程服务@DubboReference(version = "1.0.0", group = "prod")private UserService userService;
// 2. 像调用本地方法一样调用User user = userService.getUserById(1001L);<!-- XML 配置方式 --><dubbo:reference interface="com.example.UserService" version="1.0.0" group="prod" timeout="3000" retries="2" />Dubbo SPI 机制
Section titled “Dubbo SPI 机制”什么是 SPI?
Section titled “什么是 SPI?”SPI(Service Provider Interface)是 Java 提供的一种服务发现机制,允许在运行时动态加载实现类。
传统 Spring:应用定义接口,Spring 注入实现SPI:接口定义规范,运行时动态发现实现Dubbo SPI 的优势
Section titled “Dubbo SPI 的优势”// Dubbo SPI 示例:LoadBalance 接口// random = org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance// roundrobin = org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance// leastactive = org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance// consistenthash = org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance自定义 SPI 扩展
Section titled “自定义 SPI 扩展”// 1. 定义接口@SPI("dubbo")public interface Protocol { @Adaptive Exporter<?> export(Invoker<?> invoker) throws RpcException;
@Adaptive Invoker<?> refer(Class<?> type, URL url) throws RpcException;}
// 2. 实现接口public class CustomProtocol implements Protocol { @Override public Exporter<?> export(Invoker<?> invoker) { // 自定义导出逻辑 return new CustomExporter(invoker); }
@Override public Invoker<?> refer(Class<?> type, URL url) { // 自定义引用逻辑 return new CustomInvoker(type, url); }}
// 3. 配置 SPI 文件// META-INF/dubbo/org.apache.dubbo.rpc.Protocol// custom = com.example.CustomProtocol集群容错机制
Section titled “集群容错机制”Failover(失败自动切换)
Section titled “Failover(失败自动切换)”<dubbo:reference cluster="failover" retries="2" />- 调用失败时,自动切换其他服务器重试
- 适用于读操作
- retries 指定重试次数
Failfast(快速失败)
Section titled “Failfast(快速失败)”<dubbo:reference cluster="failfast" />- 调用失败立即报错
- 适用于非幂等操作(如新增数据)
Failsafe(失败安全)
Section titled “Failsafe(失败安全)”<dubbo:reference cluster="failsafe" />- 调用失败静默处理,返回空结果
- 适用于日志记录等非核心服务
Forking(并行调用)
Section titled “Forking(并行调用)”<dubbo:reference cluster="forking" forks="3" />- 并行调用多个服务器,只要一个成功就返回
- 适用于实时性要求高的场景
Broadcast(广播调用)
Section titled “Broadcast(广播调用)”<dubbo:reference cluster="broadcast" />- 逐个调用所有提供者,任意一台报错则终止
- 适用于更新缓存等场景
负载均衡策略
Section titled “负载均衡策略”1. Random LoadBalance(随机)
Section titled “1. Random LoadBalance(随机)”// 随机选择可用服务器// 权重相同时:每个服务器概率相等// 权重不同时:按权重分配概率2. RoundRobin LoadBalance(轮询)
Section titled “2. RoundRobin LoadBalance(轮询)”// 依次选择可用服务器// 缺点:不考虑服务器性能差异// 改进:加权轮询3. LeastActive LoadBalance(最少活跃数)
Section titled “3. LeastActive LoadBalance(最少活跃数)”// 选择活跃数最少的服务器// 活跃数 = 正在处理的请求数// 性能好的服务器处理更快,活跃数更少4. ConsistentHash LoadBalance(一致性 Hash)
Section titled “4. ConsistentHash LoadBalance(一致性 Hash)”// 相同参数的请求路由到同一服务器// 解决分布式缓存问题// 虚拟节点解决数据倾斜Dubbo 与 Spring Cloud 对比
Section titled “Dubbo 与 Spring Cloud 对比”| 特性 | Dubbo | Spring Cloud |
|---|---|---|
| 定位 | RPC 框架 | 微服务全家桶 |
| 通信协议 | Dubbo 协议 / HTTP | HTTP / Feign |
| 注册中心 | ZooKeeper / Nacos | Eureka / Nacos |
| 服务发现 | 多种 | 多种 |
| 负载均衡 | 多种 | Ribbon |
| 容错机制 | 多种 | Sentinel |
| 配置中心 | Apollo / Nacos | Config Server |
| 网关 | 无 | Gateway |
| 性能 | 高(TCP/NIO) | 较低(HTTP) |
| 学习成本 | 中 | 高 |
适合用 Dubbo:- 对性能要求高- Java 系技术栈- 已有 ZooKeeper 基础设施
适合用 Spring Cloud:- 多语言团队- 微服务全家桶需求- Spring 生态深度集成面试高频问题
Section titled “面试高频问题”Q1: Dubbo 的工作原理是什么?
Section titled “Q1: Dubbo 的工作原理是什么?”参考答案:
- 服务提供者启动时向注册中心注册服务
- 服务消费者启动时从注册中心订阅服务
- 注册中心返回服务提供者列表给消费者
- 消费者根据负载均衡策略选择提供者进行调用
- 监控中心统计服务调用情况
Q2: Dubbo 支持哪些序列化方式?
Section titled “Q2: Dubbo 支持哪些序列化方式?”参考答案:
- Hessian:默认序列化方式,性能好
- Java 原生:JDK 自带,不推荐(性能差、安全问题)
- Kryo:高性能序列化
- Protobuf:跨语言高性能
- FST:Java 高性能序列化
Q3: Dubbo 如何实现服务治理?
Section titled “Q3: Dubbo 如何实现服务治理?”参考答案:
- 负载均衡:Random、RoundRobin、LeastActive、ConsistentHash
- 集群容错:Failover、Failfast、Failsafe、Forking、Broadcast
- 限流降级:Sentinel 集成
- 服务路由:条件路由、脚本路由
- 动态配置:配置中心动态修改参数