
背景
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 附近
网友评论