美文网首页面试精选Java技术升华
动态限流下分布式调出限流设计与实现

动态限流下分布式调出限流设计与实现

作者: 中间件XL | 来源:发表于2021-12-14 09:00 被阅读0次

背景

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

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

参考和术语

ratelimiter  guava 流控组件

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

漏桶算法:

一个固定容量的漏桶,按照常量固定速率流出水滴;

如果桶是空的,则不需流出水滴;

可以以任意速率流入水滴到漏桶;

如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

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

令牌桶算法:

用户设定 QPS 为 r,则每隔 1/r 秒一个令牌被加入到桶中

设定桶中最多可以存放 b 个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃

当流量以速率 v 进入,从桶中以速率 v 取令牌,拿到令牌的流量通过,拿不到令牌流量不通过,执行等待或熔断

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

场景视图

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

拦截器

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

      > retrofit/okhttp3

      > httpclient

      > aop

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

设置 api 资源资源是流控目标抽象,api 看作资源,资源配置流控规则

申请 token令牌桶算法

定时重置速率作业调度作业,依据观测速率作为经验值

事件监听监听超限消息,调整 rate

输出测量api 请求集群 qps ,支持 Prometheus;console(本地测试用); NopScheduledReporter(什么都不做的报告器,相当于屏蔽)

技术架构

请求,同一个资源,任何时候,任何服务,任何实例,发出请求

资源的流量限制是动态的,资源提供者根据系统总体负载的变化而变更流量限制

拦截器 调用拦截,申请令牌,若超限发送超限消息

流量控制 令牌桶算法使用 redis lua 实现

流量规则 流量规则管理

流控速率重置作业 定时重置资源流限

事件监听 接收超限事件,调速

metrics 汇集到 Prometheus,聚合统计;  作为经验值数据支持

流量控制算法

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

详细设计

领域模型

源码

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

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

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

aop:  TestFlowSharpingAspect

okhttp:  FlowSharpingOkHttpInterceptorTest

httpclient:  FlowSharpingHttpClientTest

效果

8.1 分布式服务流控

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

1)设置资源/桶 TestFlowRuleService.testAddRedsourceFlowRule

桶配置,限流 50/分钟

使用 Prometheus 输出

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

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

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

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

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

8.2 场景: 动态变更流限

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

"15": 80 , 15 点,经验值 80

8.2.1 经验速率设置

ResourceService. setExperienceRate

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

相关文章

网友评论

    本文标题:动态限流下分布式调出限流设计与实现

    本文链接:https://www.haomeiwen.com/subject/aizatrtx.html