分布式限流/动态限流设计与实现(附源码)

1. 背景

api流控分为in/out两个方向,in控制调用者调入流量, out控制调出api流量。开源有比较多的限流框架,如guava ratelimiter,sentinel的集群流控。 ratelimiter单机版,不适合用在分布式场景;sentinel集群流控其实是限速,但api限速是动态的,我们需要调限速,根据资源情况或者api提供者的反馈,调高,调低流限,因此自研分布式api流控组件。

本组件用于系统调出第三方api流量整型,提高api调用通过率

2. 参考和术语

ratelimiter  guava流控组件

sentinel 集群流控,支持集群限流

漏桶算法:

  • 一个固定容量的漏桶,按照常量固定速率流出水滴;
  • 如果桶是空的,则不需流出水滴;
  • 可以以任意速率流入水滴到漏桶;
  • 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

通俗的比喻,门很窄,只能通过一个人

令牌桶算法:

  • 用户设定QPS为r,则每隔1/r秒一个令牌被加入到桶中
  • 设定桶中最多可以存放b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃
  • 当流量以速率v进入,从桶中以速率v取令牌,拿到令牌的流量通过,拿不到令牌流量不通过,执行等待或熔断

通俗的比喻,门很宽,门口放一个桶,桶里放着令牌,每个人要过门需要从桶里拿个令牌,凭令牌通过,桶令牌匀速投放

3. 场景视图

场景视图描述系统干了什么事,有什么价值

  • 拦截器 

   1. 拦截client调用,申请token,执行流量控制逻辑

       > retrofit/okhttp3

      > httpclient

      > aop

      > 可扩展

   2. 申请token返回调用频率太高(429),发送超限消息

  • 设置api资源  资源是流控目标抽象,api看作资源,资源配置流控规则
  • 申请token 令牌桶算法
  • 定时重置速率作业 调度作业,依据观测速率作为经验值
  • 事件监听  监听超限消息,调整rate
  • 输出测量 api请求集群qps ,支持Prometheus;console(本地测试用); NopScheduledReporter(什么都不做的报告器,相当于屏蔽)

4. 技术架构

  • 请求,同一个资源,任何时候,任何服务,任何实例,发出请求
  • 资源的流量限制是动态的,资源提供者根据系统总体负载的变化而变更流量限制
  • 拦截器 调用拦截,申请令牌,若超限发送超限消息
  • 流量控制 令牌桶算法使用redis lua实现
  • 流量规则 流量规则管理
  • 流控速率重置作业 定时重置资源流限
  • 事件监听 接收超限事件,调速
  • metrics 汇集到Prometheus,聚合统计;  作为经验值数据支持

 5. 流量控制算法

本组件使用令牌桶算法,观测作为经验值定时重置限制值; 资源调用反馈调速

6. 详细设计

领域模型

 7. 源码

源码(付费):flowsharping.rar-Java文档类资源-CSDN下载

包括流控源码,及依赖metrics-reporter,metrics输出器

测试:TestFlowSharpingMetrics,测试包括限流和metrics输出,单机可用console reporter;分布式聚合metrics需Prometheus

aop:  TestFlowSharpingAspect

okhttp:  FlowSharpingOkHttpInterceptorTest

httpclient:  FlowSharpingHttpClientTest

8. 效果

8.1 分布式服务流控

改造sentinel的okhttp和httpclient两个是单元测试,但资源名称一样 r1

1)设置资源/桶 TestFlowRuleService.testAddRedsourceFlowRule

桶配置,限流50/分钟

使用Prometheus输出器

上面两个图表两个不同的服务,同一机器,端口不同,下面图表两机器总的流量

绿色 pass流量,红色 fail流量,紫色总流量

可以看到,流量基本稳定在50左右

关掉一个服务,总体仍然保持50设定速率

 再次打开另一个服务,流量速率保持设定50

8.2 场景: 动态变更流限

8.2.1 动态变更流限通过经验速率设置,  ResourceService. updateExperienceRate

8.2.1 经验速率设置

ResourceService. setExperienceRate

其中节点A okhttp,节点B httpclient,总pass上升到80附近

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中间件XL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值