本节目录

  • 1、集群限流使用场景
  • 2、集群限流与单机限流的异同思考
  • 3、探究集群限流实现原理
    • 3.1 ClusterBuilderSlot 详解
    • 3.2 集群限流模式实现原理
      • 3.2.1 DefaultClusterTokenClient 详解
      • 3.2.2 DefaultTokenService 详解
  • 4、总结

1、集群限流使用场景

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

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

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

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

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

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

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

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

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

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

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

3.1 ClusterBuilderSlot 详解

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

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

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

NodeSelectorSlot 的关键点如下:

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

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

ClusterBuilderSlot 的关键点如下:

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

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

3.2 集群限流模式实现原理


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

代码@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 默认配置的文件如下:

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

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

这里需要说明的其配置项由 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

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

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

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

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

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

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

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

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

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

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

  • 获取当前等待的TPS(即1s为维度,当前等待的请求数量)
  • 如果当前等待的TPS低于可借用未来窗口的许可阔值时,可通过,但设置其等待时间,可以通过 maxOccupyRatio 来设置借用的最大比值。
    Step6:如果当前许可不足,并且该请求为普通优先级的处理逻辑,增加阻塞相关指标的统计数,并返回 BLOCKED。

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

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

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

4、总结

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


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

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


好了,我亲爱的读者朋友,本文的内容就介绍到这里了。原创不易,莫要白票,请你为本文点赞个吧,这将是我写作更多优质文章的最强动力。


欢迎加笔者微信号(dingwpmz),加群探讨,笔者优质专栏目录:
1、源码分析RocketMQ专栏(40篇+)
2、源码分析Sentinel专栏(12篇+)
3、源码分析Dubbo专栏(28篇+)
4、源码分析Mybatis专栏
5、源码分析Netty专栏(18篇+)
6、源码分析JUC专栏
7、源码分析Elasticjob专栏
8、Elasticsearch专栏(20篇+)
9、源码分析MyCat专栏

Sentinel 集群限流设计原理相关推荐

  1. 快速体验 Sentinel 集群限流功能,只需简单几步

    ️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器. S ...

  2. sentinel 集群限流

    sentinel 集群限流 官网:https://sentinelguard.io/zh-cn/docs/cluster-flow-control.html 集群限流 集群限流:一个服务在多个机器上部 ...

  3. Sentinel v1.4.2 发布,更好用的集群限流功能

    Sentinel 发布 v1.4.2 正式发布,该版本主要变更如下: 特性/功能改进 新增 Zuul 1.x 适配模块(sentinel-zuul-adapter),结合集群限流特性可以更好地在 AP ...

  4. 更好用的集群限流功能,Sentinel 发布 v1.4.2

    Sentinel 发布 v1.4.2 正式发布,该版本主要变更如下: 特性/功能改进 新增 Zuul 1.x 适配模块(sentinel-zuul-adapter),结合集群限流特性可以更好地在 AP ...

  5. 解决sentinel结合nacos实现集群限流(嵌入式)

    本文将为您介绍什么是集群流控,如何使用阿里的开源项目 Sentinel实现动态配置的集群流控的详细内容,以下是详情内容,希望我们能共同学习进步 Why? 为什么要用集群流控? 相对于单机流控而言,我们 ...

  6. Sentinel系统规则_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0044

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后咱们来说一下这个系统规则怎么用 可以看到系统规则,又叫系统自适应限流,就是说,sentinel ...

  7. Sentinel热点Key降级下_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0043

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 先复习一下 可以看到我们配置的是testHotKey,这个资源名,就是 @SentinelReso ...

  8. Sentinel初始化监控_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0031

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们开始配置sentinel的初始化监控功能,其实就是对我们访问的微服务进行一个保护 这个保护 ...

  9. Sentinel流控规则_关联_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0035

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 这里我们再看这个关联的意思 当关联的资源达到阀值的时候就限流自己 比如我们设置支付接口达到阀值以后 ...

最新文章

  1. 开源!《AI 算法工程师手册》中文教程正式发布!
  2. 汇聚6年思想变迁:知识图谱报告幻灯片大全
  3. 亿级流量架构之分布式事务思路及方法
  4. Controller 相关注解
  5. 简单小清新植物点缀绿色花边边框,圣诞节花环节日PNG素材
  6. js获取display的值_JS实现多行溢出省略号思路
  7. dao-service-servlet-jsp构建简易web通讯录(三层开发)bug1
  8. 用VBA模拟7段数码管显示数字
  9. JAVA企业级应用服务器之TOMCAT实战
  10. 创新创业名词解释_(完整word版)“大众创业万众创新”相关名词解释总汇
  11. php的zend引擎执行过程 一
  12. Unity2017探究Layout布局
  13. 无法实现的梦想:孤独之旅计划
  14. xpath无法定位tbody
  15. Centos7重置用户密码
  16. 李洪强iOS开发支付集成之支付宝支付
  17. [Trans 系列之一]TransE算法(Translating Embedding)
  18. 海外专利紧缺 中国IT企业国际化维艰
  19. 最新游戏评测门户资讯交流论坛网站源码+Dz内核
  20. 吴恩达机器学习17-大规模机器学习

热门文章

  1. JavaWeb学习笔记(5)-B站尚硅谷
  2. 基于FPGA的FIR调试
  3. 【人工智能项目】机器学习中文垃圾邮件分类任务
  4. gt710显卡驱动linux,Ubuntu18.04导入nVidiaGT710显卡
  5. Allergo导出Gerber文件
  6. 检测手机号码是否合法(正则表达式)
  7. Mac电脑使用:下载安装SourceTree的步骤以及使用方法
  8. 蔡崇信:一个拯救阿里巴巴的男人
  9. java实现动态规划算法解决存钱罐问题(piggy bank)
  10. 基于Java毕业设计新疆旅游专列订票系统源码+系统+mysql+lw文档+部署软件