第7章:Dubbo集群容错

第7章:Dubbo集群容错

Dubbo容错机制对上层透明(上层看不到具体的实现)

1.容错机制概述

1.1 Failover

Cluster接口上有SPI注解@SPI(FailoverCluster.NAME),即默认实现是Failover

使用for循环实现重试,for循环次数就是重试的次数。具体流程如下:

  • 校验。如果for循环次数大于1,即有过1次重试。则会再次娇艳节点是否被销毁,传入的Invoker列表是否为空。
  • 负载均衡。调用select方法做负载均衡,得到要调用的节点,并记录这个节点到保存出现异常、记录调用过哪些节点的集合中(用来做负载均衡,避免重复调用同一个节点)
  • 远程调用。调用invoker#invoke方法做远程调用,成功则返回,异常则记录异常信息,再做下次循环。

1.2 Failfast

Failfast会在失败后直接抛出异常并返回,实现非常简单。
在这里插入图片描述

1.3 Failsafe

如果抛出异常,则会直接忽略,返回一个空的结果集。
在这里插入图片描述

1.4 Failback

如果调用失败,则会定期重试。FailbackClusterInvoker里面定义了一个ConcurrentHashMap,专门用来保存失败的调用,另外定义了一个定时线程池,定时执行重试失败调用。捕获异常,只打印日志,防止异常中断重试过程。
在这里插入图片描述

1.5 Available

找到第一个可用的服务直接调用并返回结果,如果没有找到可用的Invoker,则抛出异常。

1.6 Broadcast

广播所有可用的节点,执行调用,如果任何一个节点报错,则返回异常。

如果一个节点报错,并不会中断整个广播过程,会先记录异常,在最后广播完成后在抛出。后面的异常会覆盖前面的异常

1.7 Forking

并行调用,有任何一个返回,则直接返回。

增加了接口的成功率,并行调用保证个别调用失败不返回异常信息,只有全部失败才返回异常信息:有判断条件,当失败计数>所有可用的Invoker时,才会把异常信息放入阻塞队列

主线程同步等待返回结果。主要是利用阻塞队列的poll(超时时间)实现超时等待。
在这里插入图片描述

2.Directory

整个容错过程中首先调用Directory#list获取所有的Invoker列表。静态列表是用户自己设置的Invoker列表,动态列表根据注册中心的数据动态变化。类图如下:
在这里插入图片描述

RegisterDirectory的实现(动态路由)

  • subscribe订阅某个URL的更新信息(Bean的配置在配置中心是以URL的形式存放的)
  • notify监听配置中心URL的变化,然后更新本地的配置参数

3.路由的实现

有不同的路由策略,有条件路由、文件路由、脚本路由。(都是不同的路由配置方式)

4.负载均衡的实现

1⃣️Directory获取所有的Invoker列表

2⃣️Router根据路由规则过滤Invoker

3⃣️负载均衡

负载均衡接口,默认为随机负载均衡

4.1 Random负载均衡

在这里插入图片描述

4.2 RoundRobin负载均衡

和操作系统的步长算法很相似

4.3 LeastActive负载均衡(最少活跃数,能者多劳)

配合ActiveLimitFilter过滤器来计算每个接口方法的活跃数。在ActiveLimitFilter中,只要进来一个请求,改方法的调用的计数就会原子性+1,整个Invoker调用过程在try-catch-finally中,无论调用结束或出现异常,finally中都会把计数原子性-1。该原子计数就是最少活跃数
在这里插入图片描述

4.4 一致性Hash负载均衡

可以让参数相同的请求每次都路由到相同的机器上。在每次节点上下线,请求都会平摊到相邻的服务器,不会引起服务剧烈变动。请求进来是顺时针查找最近的节点。

普通一致性Hash的缺点是每个节点分配的请求不一定均匀,改进是使用真实节点到虚拟节点的映射。虚拟节点均匀分布在环上
在这里插入图片描述

一致性Hash负载均衡使用TreeMap放置真实节点、虚拟节点

使用TreeMap的ceilingEntry方法,找到至少大于或等于当前key的Entry,如果找不到,就使用firstEntry返回第一个节点

猜你喜欢

转载自blog.csdn.net/weixin_42478399/article/details/121872097
今日推荐