系列文章
【开源】Sentinel控制台集群方案(使用Ignite解决单点故障问题)
【开源】Sentinel高性能高可用集群限流解决方案
很久前就已经开始使用Sentinel。当时为了解决其开源的控制台单点故障问题,于是开源了Sentinel控制台集群方案(使用Ignite解决单点故障问题)。当初就一直计划要做Sentinel集群限流的高性能高可用解决方案,并给大家开源。但是由于种种原因,这个事情一直没有完成。经过快两年多的时间,楼主终于该解决方法的实现,并给大家开源。今天就给大家详细介绍下Sentinel集群限流的高性能高可用解决方案。其主要涉及如下几个改造点:
1、接入协调集群节点单点故障问题
2、实现集群容错策略,实现集群不可用时主动降级本地流控
3、实现资源路由模式,解决Token Server节点流量不均问题
4、实现动态集群限流,解决单Token Server节点上限对业务的限制
我们都知道开源的Sentinel提供了一个基础版本的集群限流实现。但是要直接在业务系统中使用还是存在很多问题。其中主要的有两个:一是集群节点存在单点故障的问题。二是集群节点不可用时,没有对应的容错策略。因此我们的集群限流解决方案便主要是围绕解决这两个问题。
其实单点故障的解决方案比较简单,我们只需要在集群节点(Token Server)和客户端之间构建一个高可用协调集群即可。这里我们可以选择zookeeper或者ETCD。这样我们就可以部署很多Token Server节点构建一个Token Server集群,当集群节点变更之后,就能够实时通知到客户端,客户端则可以及时获取到当前可用的集群节点信息。从而解决了Token Server单点故障的问题。其大致架构如下:
我们都知道咱们得客户端SDK需要连接并请求对应的Token Server节点,去实时判断计数才能实现集群限流。但当我们的Token Server节点挂了之后,我们怎么去判断该节点不可用并终止请求呢?如果我们不做任何判断,则会出现大量无效调用对客户端SDK性能也会有影响,且对业务也会产生影响。因此,我们需要判断出Token Server挂了,并主动将集群流控降级为本地流控。
我们设计了DiagnoseFaultToleranter,来判断Token Server是否可用。大概思路就是:通过滑动窗口来统计该节点的请求可用率或者异常数。然后根据设置阈值来判断是否该节点是否可用。
这样我们就能够判断Token Server是否可用,并执行相应的降级策略了。
解决了前面两个问题之后,咱得集群限流基本就可以在线上系统使用了。至少其满足了高可用的特性,不再具有单点故障问题。但是我们还可以做进一步的优化改进。
由于Sentinel开源默认集群限流的时候的路由方式为系统维度路由:及一个系统下的所有资源(接口)都路由到一个Token Server上进行计数统计。这样如果我们有多个系统需要接入集群限流集群,且每个系统的流量差距很大,就会导致Token Server节点之间的流量差距很大,导致资源无法得到充分利用。如下图,如果系统A和系统B的流量差距很大,则会导致节点1和节点2承载的流量非常不均匀。
因此我们需要改造支持按资源(接口)维度进行路由。这样才能够尽量让Token Server之间的流量差距变小,让其资源得到充分利用。如下图根据细粒度的资源维度进行路由,则能很好的解决节点流量承载不均的问题。
代码实现上我们使用了MappedClusterTokenClient来支持资源路由,使用SystemClusterTokenClient来支持系统路由。同时设计了代理模式,使用了ClusterTokenClientProxy来根据配置代理选择咱们最终的TokenClient。
4、动态集群限流
未完待续...
开源地址:https://github.com/lifeofcoder/AutoLimiter
https://github.com/lifeofcoder/AutoLimiter
如果你喜欢本文或觉得本文对你有所帮助,欢迎一键三连支持,非常感谢。
如果你对本文有任何疑问或者高见,欢迎添加公众号lifeofcoder共同交流探讨(添加公众号可以获得楼主最新博文推送以及”Java高级架构“上10G视频和图文资料哦)。