Fork me on GitHub

Spring Cloud Alibaba Nacos路由策略之保护阈值!

在 Nacos 的路由策略中有 3 个比较重要的内容:权重、保护阈值和就近访问。因为这 3 个内容都是彼此独立的,所以今天我们就单独拎出“保护阈值”来详细聊聊。

保护阈值

保护阈值(ProtectThreshold):为了防止因过多实例故障,导致所有流量全部流入剩余健康实例,继而造成流量压力将剩余健康实例被压垮形成雪崩效应。应将健康保护阈值定义为⼀个 0 到 1 之间的浮点数。当域名健康实例数占总服务实例数的比例小于该值时,无论实例是否健康,都会将这个(健康或不健康的)实例返回给客户端。这样做虽然损失了⼀部分流量,但是保证了集群中剩余健康实例能正常工作。

也就是说,保护阈值是设置集群中健康实例占比允许的最小值,它需要设置一个 0-1 的浮点值,默认值为 0,当集群中的健康实例占比小于设置的保护阈值时,就会触发阈值保护功能。保护阈值可在服务详情中查询和设置,如下图所示:
image.png

如何理解保护阈值?

要理解保护阈值先要明确一个前提条件:对于 Nacos 的注册中心功能来说,Nacos 有一个天然的职责,是将服务消费者(Consumer)的请求转发给某个健康的服务提供者(Provider)。
但在执行的流程中,可能会出现一种极端的情况,比如某个服务有 100 个实例,其中 99 个实例都宕机了,只剩下一个健康的实例,这个时候如果把所有的请求都转发到这一个健康实例上就会造成雪崩效应,最终导致业务系统崩溃。
为了防止这种极端情况,于是就有了“保护阈值”,保护阈值一旦被触发,那么 Nacos 将会把请求转发给所有服务实例,也就是健康实例+非健康实例,这样可能会损失了⼀部分流量,但能保证集群中剩余的健康实例能正常工作。

保护阈值触发条件:(实际健康实例/总服务实例)≤设置的保护阈值

设置保护阈值

我们可以通过“编辑服务”来设置保护阈值,如下图所示:
image.png

触发保护阈值

接下来我们创建一个服务测试一下保护阈值的功能,在创建的服务中添加两个实例,如下图所示:
image.png
image.png
默认情况下服务实例都是健康的,接下来我们将保护阈值设置为 0.8,也就是健康实例的最低要求是 80%,如果健康实例占比小于此值就会触发保护阈值,如下图所示:
image.png
当所有节点都健康时,观察服务列表页面,可以看出并未触发保护阈值的功能,如下图所示:
image.png
此时我们手动停止一个服务实例,如下图所示:
image.png
这是健康实例的占比就从 100%,下降到了 50%,小于了设置的保护阈值 0.8(80%),接下来返回服务列表页面,可以看到保护阈值功能被触发了:
image.png
此时,我们再去访问服务就会看到,部分请求会转发到非健康实例,也就是访问会出错,如下图所示:
触发保护阈值.gif

未触发保护阈值

接下来我们降低保护阈值,将保护阈值设置为 0.3,也就是健康实例占比最低要求是 30%,否则会触发阈值保护,如下图所示:
image.png
而此时因为我们健康实例占比是 50%,大于设置的阈值保护 0.3,所以就不会触发阈值保护,这点可以在服务列表中观察到:
image.png
当未触发保护阈值时,Nacos 会把所有请求都转发到健康的实例上,所以每次都能正常的访问服务,执行效果如下图所示:
保护阈值未生效.gif

总结

保护阈值是为了防止因过多实例故障,导致所有流量全部流入剩余健康实例,继而造成流量压力将剩余健康实例被压垮形成雪崩效应。它的默认值是 0,取值范围应该是 0-1 的浮点数。此值是定义集群中允许健康实例占比的最小值,如果实际健康服务占比小于或等于此值,就会触发保护阈值,那么 Nacos 就会将全部实例:健康实例 + 非健康实例全部返回给调用者,而当保护阈值未触发时,Nacos 只会把健康实例返回给调用者。

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java中文社群

Java面试合集:https://gitee.com/mydb/interview

posted @ 2022-02-14 10:05  磊哥|www.javacn.site  阅读(1614)  评论(0编辑  收藏  举报