Dubbo Cluster#
简介#
集群
Cluster用途是将多个服务提供者合并为一个Cluster Invoker,并将这个Invoker暴露给服务消费者集群模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜
集群容错#

集群工作过程可分为两个阶段:
在服务消费者初始化期间,集群
Cluster实现类为服务消费者创建Cluster Invoker实例,即上图中的merge操作在服务消费者进行远程调用时。以
FailoverClusterInvoker为例,该类型Cluster Invoker首先会调用
Directory的list方法列举Invoker列表(可将Invoker简单理解为服务提供者)。Directory的用途是保存Invoker,可简单类比为List<Invoker>注册中心内容变化后,
RegistryDirectory会动态增删Invoker,并调用Router的route方法进行路由,过滤掉不符合路由规则的Invoker当
FailoverClusterInvoker拿到Directory返回的Invoker列表后,它会通过LoadBalance从Invoker列表中选择一个Invoker最后
FailoverClusterInvoker会将参数传给LoadBalance选择出的Invoker实例的invoke方法,进行真正的远程调用
Dubbo 主要提供了这样几种容错方式:
Failover Cluster - 失败自动切换
Failfast Cluster - 快速失败
Failsafe Cluster - 失败安全
Failback Cluster - 失败自动恢复
Forking Cluster - 并行调用多个服务提供者
源码分析#
1 Cluster 实现类分析#
Cluster 是接口,而 Cluster Invoker 是一种 Invoker。服务提供者的选择逻辑,以及远程调用失败后的的处理逻辑均是封装在 Cluster Invoker 中
FailoverCluster: 用于创建FailoverClusterInvoker对象FailbackCluster: 用于创建FailbackClusterInvoker对象
2 Cluster Invoker 分析#
AbstractClusterInvoker: 各种Cluster Invoker的父类AbstractClusterInvoker+invoke(final Invocation invocation): 用于列举Invoker,以及加载LoadBalance。最后再调doInvoke进行后续操作AbstractClusterInvoker#doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance): 抽象方法,由子类实现AbstractClusterInvoker#list(Invocation invocation): 调用Directory的list方法
2.1 FailoverClusterInvoker#
FailoverClusterInvoker 在调用失败时,会自动切换 Invoker 进行重试。默认配置下,Dubbo 会使用这个类作为缺省 Cluster Invoker
doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance):获取重试次数
根据重试次数进行循环调用,失败后进行重试。在
for循环内:通过负载均衡组件选择一个
Invoker再通过这个
Invoker的invoke方法进行远程调用如果失败了,记录下异常,并进行重试。重试时会再次调用父类的
list方法列举Invoker
select(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers,List<Invoker<T>> selected):获取
sticky配置,sticky表示粘滞连接。所谓粘滞连接是指让服务消费者尽可能的调用同一个服务提供者,除非该提供者挂了再进行切换检测
invokers列表中是否包含stickyInvoker,如果不包含,则认为该stickyInvoker不可用,此时将其置空。这里的invokers列表可以看做是存活着的服务提供者列表如果
stickyInvoker存在于invokers列表中,检测selected中是否包含stickyInvoker如果包含,说明
stickyInvoker在此之前没有成功提供服务(但其仍然处于存活状态)如果不包含,此时还需要进行可用性检测,比如检测服务提供者网络连通性等
当可用性检测通过,才可返回
stickyInvoker,否则调用doSelect方法选择Invoker如果
sticky为true,此时会将doSelect方法选出的Invoker赋值给stickyInvoker
doSelect(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers,List<Invoker<T>> selected):通过负载均衡组件选择
Invoker如果选出来的
Invoker不稳定,或不可用,此时需要调用reselect方法进行重选
reselect(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers,List<Invoker<T>> selected, boolean availablecheck):查找可用的
Invoker,并将其添加到reselectInvokers集合中如果
reselectInvokers不为空,则通过负载均衡组件再次进行选择
2.2 FailbackClusterInvoker#
FailbackClusterInvoker
doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance): 负责初次的远程调用addFailed(Invocation invocation, AbstractClusterInvoker<?> router): 在开始阶段会根据retryFuture为空与否,来决定是否开启定时任务retryFailed(): 包含了失败重试的逻辑对
failed进行遍历依次对
Invoker进行调用调用成功则将
Invoker从failed中移除,调用失败则忽略失败原因
2.3 FailfastClusterInvoker#
FailfastClusterInvoker
doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance):通过
select方法选择Invoker进行远程调用。如果调用失败,则立即抛出异常
2.4 FailsafeClusterInvoker#
失败安全是指,当调用过程中出现异常时,FailsafeClusterInvoker 仅会打印异常,而不会抛出异常
应用场景:写入审计日志等操作
doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
2.5 ForkingClusterInvoker#
ForkingClusterInvoker: 在运行时通过线程池创建多个线程,并发调用多个服务提供者。只要有一个服务提供者成功返回了结果,doInvoke 方法就会立即结束运行
应用场景:在一些对实时性要求比较高读操作(注意是读操作,并行写操作可能不安全)下使用,但这将会耗费更多的资源
doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance):选出
forks个Invoker,为接下来的并发调用提供输入通过线程池并发调用多个
Invoker,并将结果存储在阻塞队列中从阻塞队列中获取返回结果,并对返回结果类型进行判断。如果为异常类型,则直接抛出,否则返回
2.6 BroadcastClusterInvoker#
BroadcastClusterInvoker 会逐个调用每个服务提供者,如果其中一台报错,在循环调用结束后,BroadcastClusterInvoker 会抛出异常
应用场景:通知所有提供者更新缓存或日志等本地资源信息
doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)