跳至正文
来两杯美式
返回

Dubbo 集群容错:架构、五种模式与服务暴露

By 来两杯美式
发布于

上一篇 《Dubbo 负载均衡:四种策略与源码分析》 讲了流量怎么分。这一篇讲失败怎么办——服务调用失败时,Dubbo 怎么容错、怎么重试,以及集群容错的整体架构。

集群容错架构图

先看整张调用链架构图:

Dubbo 集群容错架构:Cluster/Directory/Router/LoadBalance/Invoker

一次调用从发起到执行,完整经过五个环节:

外部请求 invoke

Invoker(集群入口,持有 Cluster)
     ↓  merge(集群合并,按容错模式包装)
Cluster(集群容错,5 种模式:Failover/Failfast/Failsafe/Failback/Forking)
     ↓  list
Directory(服务目录,从注册中心拿到 List<Invoker>:Registry/Static)
     ↓  List<Invoker>
Router(路由规则,过滤掉不能执行的 Invoker:Script/Condition)
     ↓  List<Invoker>
LoadBalance(负载均衡,选出一个 Invoker:Random/RoundRobin/LeastActive)
     ↓  Invoker
最终执行远程调用

调用链的职责分工:

环节职责内置实现
Cluster集群容错入口,决定失败后怎么处理Failover、Failfast、Failsafe、Failback、Forking
Directory服务目录,提供本次集群的全部 InvokerRegistry(从注册中心)、Static(直连静态)
Router路由规则,从全部 Invoker 中筛掉不可用的Script、Condition
LoadBalance负载均衡,从可用 Invoker 中选一个执行Random、RoundRobin、LeastActive

一次调用的四个步骤

笔记里原话拆解:

  1. Directory 中找出本次集群中的全部 invokers。
  2. Router 中,将上一步的全部 invokers 挑选出能正常执行的 invokers。
  3. LoadBalance 中,将上一步能正常执行的 invokers 中,根据配置的负载均衡策略,挑选出需要执行的 invoker。
  4. 执行 invokers 时,例如在默认的 FailoverClusterInvoker 中执行,根据配置的重试次数失败重试。
全部 Invoker(Directory 从注册中心获取)
   ↓ Router 过滤
可用的 Invoker(剔除路由规则排除的)
   ↓ LoadBalance 选择
选中的一个 Invoker
   ↓ Cluster 容错执行(如 Failover 失败重试)
调用完成

五种容错模式

cluster 属性决定失败时的行为:

模式类名失败后行为适用场景
FailoverFailoverClusterInvoker失败自动切换,重试其他节点默认;读操作
FailfastFailfastClusterInvoker失败立即报错,不重试非幂等写操作
FailsafeFailsafeClusterInvoker失败吞掉异常,只记日志无关紧要的旁路调用
FailbackFailbackClusterInvoker失败自动记录,定时重发消息通知、异步任务
ForkingForkingClusterInvoker并行调用多个节点,任一成功即返回高实时性读操作
<!-- 默认 Failover:重试 2 次 -->
<dubbo:reference id="userService" interface="com.example.UserService"
                 cluster="failover" retries="2"/>

Failover:失败自动切换(默认)

失败后自动切换到其他节点重试,retries 控制重试次数:

调用 A 失败 → 重试 B → 重试 C ...(最多 retries 次)

Failfast:快速失败

只调用一次,失败立即抛出异常,不重试:

调用 A 失败 → 立即抛出异常

Failsafe:失败安全

失败后吞掉异常,只记录日志,不抛给调用方:

调用 A 失败 → 记录日志 → 正常返回(假装成功)

Failback:失败自动恢复

失败后记录失败请求,定时重发(异步补偿,不再同步等待):

调用 A 失败 → 记录到失败队列 → 后台定时重试

Forking:并行调用

并行调用多个节点forks 指定并行数),任一成功即返回

同时调用 A、B(forks=2)
A 成功 → 立即返回,B 的结果丢弃
A、B 都失败 → 抛异常

容错模式选型总结

业务场景推荐模式原因
读操作、默认Failover失败重试,提升成功率
下单、扣款等写操作Failfast防重复扣款,不重试
日志、上报等旁路Failsafe失败不影响主流程
消息通知、异步Failback定时重发,最终一致
高实时读操作Forking并行调用,最快成功

服务暴露:URL → Invoker → Exporter

集群容错讲的是消费侧,最后补一块生产侧的核心原理——服务暴露

笔记里的原话一句话概括:

服务暴露:URL 转为 Invoker,Invoker 转为 Exporter。

展开看:

服务暴露(Provider 侧启动流程)
====================
1. 解析配置 → 生成服务对应的 URL
   (dubbo://10.129.83.213:20888/com.example.UserService?...)
2. URL 转为 Invoker
   (把 URL 描述的远程服务包装成可调用对象,持有协议、地址、序列化方式)
3. Invoker 转为 Exporter
   (Exporter 把 Invoker 暴露出去:启动 Netty 监听端口 + 向注册中心注册)

对应到架构图里,Consumer 侧的 Invoker 是”远程调用的抽象”,Provider 侧的 Invoker 是”本地实现的包装”——两边都是 Invoker,一侧负责发、一侧负责收,这也是 Dubbo 透明化调用的核心设计。

服务引用的镜像流程

消费侧的”服务引用”是暴露的逆过程:

1. Consumer 从注册中心拿到服务 URL
2. URL 转为 Invoker(代理对象,真正调用时发出 RPC 请求)
3. Invoker 转为代理类(用户拿到的是接口代理,调方法即远程调用)

所以用户代码里 @Reference 注入的 UserService,本质是 Dubbo 生成的动态代理,调用方法时由代理把参数序列化、发到 Provider、反序列化结果返回——这就是”透明化”的真相。

小结

至此 Dubbo 系列五篇完结:入门 → 服务拆分 → 注册中心与直连 → 负载均衡 → 集群容错。欢迎收藏,后续有新的 Dubbo 实践再补充。


分享这篇文章:
通过邮件分享这篇文章✓ 链接已复制
所属专题
Dubbo
第 4 / 5 篇
查看系列全部文章
  1. 01.Dubbo 入门:什么是 RPC 与服务治理?
  2. 02.Dubbo 注册中心与直连调试:只订阅、只注册、多注册中心
  3. 03.Dubbo 负载均衡:四种策略与源码分析
  4. 04.Dubbo 集群容错:架构、五种模式与服务暴露
  5. 05.Dubbo 服务拆分与架构设计:子系统划分的四大原则

上一篇
Dubbo 服务拆分与架构设计:子系统划分的四大原则
下一篇
Dubbo 负载均衡:四种策略与源码分析