Sentinel 集群限流设计原理

简介: Sentinel 集群限流设计原理

1、集群限流使用场景


首先一个服务有三个服务提供者,但这三台集群的硬件配置不一样,如图所示:

5df4f75197a8460ded429d8dac41cd97.png

为了充分利用硬件的资源,诸如 Dubbo 都提供了基于权重的负载均衡机制,例如可以将8C16G的机器设置的权重是4C8G的两倍,这样充分利用硬件资源,假如现在需要引入 Sentinel 的限流机制,例如为一个 Dubbo 服务设置限流规则,这样由于三台集群分担的流量不均匀,会导致无法重复利用高配机器的资源。


假设经过压测,机器配置为C48G最高能承受的TPS为 1500,而机器配置为8C16G能承受的TPS为2800,那如果采取单机限流,其阔值只能设置为1500,因为如果超过1500,会将4C8G的机器压垮。


解决这种办法的方式就是针对整个集群进行限流,即为整个集群设置一个阔值,例如设置限流TPS为6000。


2、集群限流与单机限流的异同思考


限流的一个基本作用就是按照限流规则生成访问许可(Token),然后根据当前实时的调用信息进行判断是否可以获得许可而决定是否放行。


集群与单机限流在实时调用信息收集方面应该差别不大,都可以基于滑动窗口进行统计信息的收集。


集群与单机限流的最主要区别在与许可的生成,单机模式的许可直接在本地生成,但集群限流必须有一个统一的 Token 发放机制,以此来协调当前集群内多机调用,从而基于当前“调用总数”进行限流。


3、探究集群限流实现原理


在探究集群限流实现原理之前先来回顾一下单机限流的执行流程图。

ea1c690c675cc98c91df521f07856f1b.png

结合流程我们可以看出集群限流的几个关键点 ClusterBuilderSlot、FlowSlot。


3.1 ClusterBuilderSlot 详解


在对一个资源进行流控规则判断时,首先将进入到 NodeSelectorSlot,然后就会进入到 ClusterBuilderSlot,为了与单机限流模式,介绍 ClusterBuilderSlot 时与 NodeSelectorSlot 进行一个对比。


NodeSelectorSlot 的核心实现截图如下所示:

af97e89068067ea7513e0800bf05398a.png

温馨提示:从该系列之前的文章也能得知,一个 资源对应的一个 NodeSelectorSlot  实例,即多线程访问一个资源时,都会调用同一个 NodeSelectorSlot 实例。


NodeSelectorSlot 的关键点如下:


  • Map map
    在 NodeSelectorSlot 中是以 context Id 为维度进行缓存的,例如官方给出的 Dubbo 适配方法,contexId 为 dubbo 服务的全路径名。即 Dubbo的入口节点对应的缓存 Key 为 context
    id。
  • fireEntry 的 node 参数
    由于 NodeSelectorSlot 是第一个过滤器,故第一次调用 fireEntry 方法时的 node 参数就是上面创建的 Node,即与 context 相关链的 Node,即所谓的入口节点即 Entrance Node。


接下来重点关注一下 ClusterBuilderSlot 的关键点:

081670f4937ddf1bebb638d3473d7760.png

ClusterBuilderSlot 的关键点如下:


  • Map clusterNodeMap
    持有的集群节点缓存表,其键为 Entrance Node 所对应的资源ID,即 Context 中关联的节点信息。
  • Node originNode
    所谓的 orginNode,即在调用 ContextUtil 中 enter(String name, String origin) 方法中的第二个参数,表示这条调用链的源头,在 Dubbo 中默认为 应用的 application。


经过上面两个Slot,整个调用链就基本创建好了,接下来我们来看一下 FlowSlot 关于集群限流的相关处理逻辑。


3.2 集群限流模式实现原理


47d0ca876718ae812f753966f60cf050.png

FlowSlow FlowSlot 的核心处理逻辑主要是调用 FlowRuleChecker 的 canPassCheck 方法,正如上面看到的一样,根据配置规则,如果是集群模式,则调用的是其 passClusterCheck 方法,接下来我们将重点探讨该方法。

724040a897de8f7204fa7469785fae19.png

代码@1:获取一个 TokenService 服务类。这里实现关键点:


  • 如果当前节点的角色为 CLIENT,返回的 TokenService 为 DefaultClusterTokenClient。
  • 如果当前节点的角色为 SERVER,返回的 TokenService 为 ClusterTokenServer,这里使用了SPI极致,可以通过查看 META-INF/services 目录下的 com.alibaba.csp.sentinel.cluster.TokenService 文件,默认服务端返回 DefaultTokenService。


代码@2:如果无法获取到集群限流Token服务,如果该限流规则配置了可以退化为单机限流模式,则退化为单机限流。


代码@3:获取集群限流的流程ID,该 flowId 全局唯一。


代码@4:通过 TokenService 去申请 token,这里是与单机限流模式最大的差别。


接下来将分别从 DefaultClusterTokenClient、DefaultTokenService 分别探究集群限流相关的实现原理与细节,更好的指导我们如何使用集群限流功能。


3.2.1 DefaultClusterTokenClient 详解


从我们的经验也得知,TokenClient 的主要职责就是发送请求到 TokenService 端,主要是网络相关的细节将不在此篇文章中给出,如果有兴趣,大家可以关注我的 Netty 专栏。


首先 Sentinel 提供了 SPI 机制,故允许用户自定义 TokenClient 的实现类,官方与 SPI 默认配置的文件如下:


737b45be434bd843492d8124a40b0884.png

关于 TokenClient 主要关注其初始化代码,因为我们需要关注一个非常重要的点:


DefaultClusterTokenClient#initNewConnection

9ff2c399adb0aebf93aca4217e47aa10.png


在客户端启动的时候会创建与 TokenServer 之间的链接,即这边需要配置服务端的 IP 与端口号,那如何配置呢?其实配置方式完全由自己去实现对应的解析器,下面根据官方的 Demo 示例如下:

80fa52951def982bb7360d0fda994841.png


这里需要说明的其配置项由 ClusterGroupEntity 来定义,其字段的定义如下:


  • clientSet
    客户端 Set 集合。
  • ip
    Token 服务端的 IP。
  • machinedId
    Token 服务端的机器ID。
  • port
    Token 服务端的机器端口。


其配置示例如下:


[{"clientSet":["112.12.88.66@8729","112.12.88.67@8727"],"ip":"112.12.88.68","machineId":"112.12.88.68@8728","port":11111}]


Client 端接下来就是向服务端发送请求,与网络相关的不在本文的讨论范围内,接下来将重点探讨服务端是如何发放许可的。


3.2.2 DefaultTokenService 详解


Token Server 端收到客户的请求,其处理入口为 FlowRequestProcessor,其处理方法为:processRequest,最终会调用 DefaultTokenService 的 requestToken 方法。


DefaultTokenService#requestToken


11f1edded9cf10137ed75dcf340e73d3.png

代码@1:根据 ruleId 获取指定的限流规则。


代码@2:然后调用 ClusterFlowChecker 的 acquierClusterToken 方法,申请许可。


许可的发放流程主要由 ClusterFlowChecker 的 acquierClusterToken 方法实现。

6205015faa3a39c948e99ce21d721118.png

Step1:首先判断是否允许本次许可申请,这是因为 TokenServe 支持嵌入式,即支持在应用节点中嵌入一个 TokenServer,为了保证许可申请的请求不对正常业务造成比较大的影响,故对申请许可这个动作进行了限流。


一旦触发了限流,将向客户端返回 TOO_MANY_REQUEST 状态码,Sentinel 支持按 namespace 进行限流,具体由 GlobalRequestLimiter 实现,该类的内部同样基于滑动窗口进行收集,原理与 FlowSlot 相似,故这里不加以展开,默认的限流TPS为3W,有关于 Sentinel 相关的配置,将在后续文章专门梳理。


8ea7dde1a34bd832bf0fbbb8511b7746.png

Step2:根据流程ID获取指标采集器。

9692ddd4d90365acefd3d3cb2c3b21b5.png

Step3:计算 latestQps、globalThreashold、 nextRemaining 三个阔值,三个的含义分别如下:


  • latestQps
    获取当前正常访问的QPS。
  • globalThreashold
    根据限流配置规则得出其总许可数量,其主要根据阔值的方式其有所不同,其配置阔值有两种方式:
    1)FLOW_THRESHOLD_GLOBAL
    总数,即集群中的许可等于限流规则中配置的 count 值。
    2)FLOW_THRESHOLD_AVG_LOCAL
    单机分摊模式,此时限流规则中配置的值只是单机的 count 值,集群中的许可数等于 count * 集群中客户端的个数。
    注意:这里还可以通过 exceedCount 设置来运行超过其最大阔值,默认为1表示不允许超过。
  • nextRemainging
    表示处理完本次请求后剩余的许可数量。

321aec07d500a260b85ca4b262a9f44d.png

  • Step4:如果剩余的许可数大于0,则本次申请成功,将当前的调用计入指标采集器中,然后返回给客户即可。


接下来所有流程步骤都是基于没有剩余许可数的处理逻辑。

4b6735ad6437bb7613feb876fd4d5208.png

Step5:当前许可数不足的情况,并且该请求为高优先级的处理逻辑:


  • 获取当前等待的TPS(即1s为维度,当前等待的请求数量)
  • 如果当前等待的TPS低于可借用未来窗口的许可阔值时,可通过,但设置其等待时间,可以通过 maxOccupyRatio 来设置借用的最大比值。

af58a3a69b06a4a172e526bbf21db20d.png

  • Step6:如果当前许可不足,并且该请求为普通优先级的处理逻辑,增加阻塞相关指标的统计数,并返回 BLOCKED。


TokenServer 返回申请许可之后,那 Token Client 如何处理呢?其处理代码在 FlowRuleChecker#applyTokenResult

91caa0fd939cb70ac9284fdcf7dbf9d5.png


我们可以发现,如果服务端返回OK,则顺利通过,返回BLOCKED,则直接返回 false,会抛出 FlowException,如果是 token 限流,如果规则运行退化为单机限流模式,则进行单机限流。


集群限流的基本实现原理就介绍到这里了。


4、总结


集群限流的基本原理接介绍到这里了,与单机限流模式最大的区别就是集群限流模式的需要引入 TokenService,提供许可的发放服务,该服务可以嵌入应用节点,也可以独立于应用之外。这边借用官方文档上的两张图来简单介绍一下嵌入模式与独立模式的架构:

555dcfa0414cb74063c6154d0e4a4b4e.png

9ab9b91da826ec0591c1636edb17bb44.png

集群模式使用注意,如果使用的是集群模式限流,则如下两个配置则失效:

07aa62b30ccb419ccc51cc0c99a7515f.png

最后抛出一个思考题:集群模式应该算是高大上,但我们项目中真的需要吗?集群限流模式有哪些缺点、哪些优点,欢迎大家留言探讨。

相关文章
|
6月前
|
监控 Java Sentinel
使用Sentinel进行服务调用的熔断和限流管理(SpringCloud2023实战)
Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
157 3
|
2月前
|
负载均衡 算法 Java
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
40岁老架构师尼恩分享了关于SpringCloud核心组件的底层原理,特别是针对蚂蚁集团面试中常见的面试题进行了详细解析。内容涵盖了Nacos注册中心的AP/CP模式、Distro和Raft分布式协议、Sentinel的高可用组件、负载均衡组件的实现原理等。尼恩强调了系统化学习的重要性,推荐了《尼恩Java面试宝典PDF》等资料,帮助读者更好地准备面试,提高技术实力,最终实现“offer自由”。更多技术资料和指导,可关注公众号【技术自由圈】获取。
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
|
2月前
|
运维 监控 算法
聊一聊Sentinel背后的原理
本文介绍了Sentinel的核心原理,包括流量控制、熔断降级、系统负载保护、实时监控和统计、与多种微服务框架的集成能力以及扩展性,强调了Sentinel在保障分布式系统稳定性方面的重要性。
129 0
|
4月前
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
|
5月前
|
监控 算法 Java
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
|
6月前
|
监控 Java 应用服务中间件
Sentinel原理及实践
Sentinel原理及实践
117 1
|
7月前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
7月前
|
SpringCloudAlibaba 监控 Java
SpringCloud Alibaba Sentinel实现熔断与限流--学习笔记
SpringCloud Alibaba Sentinel实现熔断与限流--学习笔记
110 0
|
7月前
|
监控 算法 Java
sentinel 服务限流工作原理
sentinel 服务限流工作原理
|
4月前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
87 1