一种巧妙的动态分级限流方案

前言

在后端业务支持中,服务的稳定性保障是最重要的工作内容,其中对于上游服务限流是经常需要采用的方案,这样可以保证自身业务的稳定性与上游流量波动解耦。而在多数场景我们需要面临的上游比较多,单调的配置只一个限流阈值,可能会无法实现对于每个业务方的不同场景的限流控制。

在这样的前提下,通常选择对于每个上游业务的流量打标记,每个业务方分配不同的限流阈值才能达到效果,如:总限流1000,A业务最重要限流500,B业务次之限流300,C业务优先级最低分配200。但这样的一个很明显的缺点就是,如果上游业务方的高峰期时间都不一致,但是我们又需要提供总1000qps的系统能力,就会造成资源的浪费无法复用其他业务方的空闲时间释放出来资源给其他业务方使用。

本文基于上述背景,提供一个灵活的应对多业务方的动态分级限流方案供大家参考。

正文

动态分级限流思路

要实现灵活的动态分级限流,同样是需要使用中心式限流的方案(由限流中间件下发限流令牌的方式承接)。主要实现思路分为三个环节如下图:

1. 流量打标区分

我们需要对所有上游的服务流量进行优先级区分,分为P0、P1、P2三个等级,按照强弱排序,在流量上打上优先级标识,默认的其他流量打上默认优先级如P1。

2. 不同优先级的服务流量获取不同的限流令牌

此时我们需要对不同优先级的流量去申请限流令牌,这里是实现的重点,我们需要对P0级(最高优先级)的流量申请该级别以及该级别以下的所有令牌;对于P1级的流量同样申请该级别以及该级别以下的所有令牌;最后到P2级,只申请当前级别令牌即可。

每个优先级桶的个数,按需计算一个合理的阈值。其中P0级的限流令牌不会被其他优先级所干扰,因此为确定性的阈值;P1级的限流令牌个数会被P0的流量所积压,所以P1的日常流量=P1的配置-P0的日常流量,如果P0配置的是300,P1配置的是500,则P1在极端场景下只有200的令牌数量;如果P1配置的是200,那么在极端场景下是所有流量都会被限流的。P2也可按照这样推理。最终整个系统可承载的最大流量值,是由最低优先级P2的令牌阈值来限制的。

其他的一些细节:

  1. 关于优先级的个数可以按需设置;
  2. 流量的打标不限于上游服务的服务名,可以是业务场景等;
  3. 对于高优先级的流量申请多个限流令牌可以通过批量请求的方式实现,异步获取结果;

3. 不同优先级根据申请令牌结果判断限流效果

在第2步完成令牌申请后,就需要根据令牌申请结果返回不同的限流效果。即:每个优先级的限流结果,只会被当前优先级令牌申请的结果限制,比它优先级低的令牌申请,并不会限制其限流效果

总结

通过上述的方案,我们能实现的效果如下:

  1. P2级别的令牌阈值可以对系统整体流量把控;
  2. P2和P1分别对高优先级的流量有避让效果,如果有高优先级的流量进来,会先保高优的流量,整个过程是算法动态调节的;
  3. 每个优先级的令牌阈值可以手动调整组合以实现不同的效果,如:完全保高优流量;
  4. 在流量打标环节,可以做成配置化的能力,通过对流量整体的基础数据采集后,通过不同的属性动态打上不同的标记(这块实现后续会单独分享)。

以上就是关于动态分级限流的基本方案了,基于算法思想的实现。

相关推荐
鱼跃鹰飞几秒前
Leetcode面试经典150题-94.二叉树的中序遍历
算法·leetcode·面试
Roam-G6 分钟前
Java 中常用的排序算法
数据结构·算法·排序算法
hjxxlsx8 分钟前
插入与冒泡排序(C++)
c++·算法·排序算法
Skrrapper9 分钟前
【数据结构】排序算法系列——快速排序(附源码+图解)
c语言·数据结构·算法·排序算法
Mephisto.java12 分钟前
【力扣 | SQL题 | 每日三题】力扣175, 176, 181
sql·算法·leetcode
木向21 分钟前
leetcode第十二题:整数转罗马数字
c++·算法·leetcode·职场和发展
繁星璀璨G25 分钟前
C++11标准模板(STL)- 常用数学函数 - 计算e的给定幂 (ex)(std::exp, std::expf, std::expl)
开发语言·c++·算法·stl·计算e的给定幂
X² 编程说31 分钟前
14.面试算法-字符串常见算法题(三)
java·数据结构·后端·算法·面试
S01d13r42 分钟前
LeetCode 每周算法 6(图论、回溯)
算法·leetcode·图论
程序员波特1 小时前
初识算法
数据结构·算法·leetcode