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

前言

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

在这样的前提下,通常选择对于每个上游业务的流量打标记,每个业务方分配不同的限流阈值才能达到效果,如:总限流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. 在流量打标环节,可以做成配置化的能力,通过对流量整体的基础数据采集后,通过不同的属性动态打上不同的标记(这块实现后续会单独分享)。

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

相关推荐
swipe6 分钟前
05|(前端转后全栈)不手写一堆 SQL,后端怎么操作数据库?MyBatis-Plus 入门
前端·后端·全栈
霸道流氓气质7 分钟前
SpringBoot中使用JasperReports 报表引擎 — 介绍、原理与使用实践
java·spring boot·后端
swipe10 分钟前
04|(前端转后全栈)前端状态为什么不够用?从页面数据到 MySQL 持久化
前端·后端·全栈
苏三说技术13 分钟前
为什么越来越多人使用WebFlux?
后端
闪电悠米17 分钟前
力扣hot100-54.螺旋矩阵-模拟边界控制详解
算法·leetcode·矩阵
变量未定义~25 分钟前
虚拟节点-星石传送阵(4星)、强连通分量
数据结构·算法
武子康29 分钟前
Ask/Allow 不是安全边界:企业 Coding Agent 必须建立四层治理(Policy / Scoped Credential / Sandbox / Provenance)
人工智能·后端·agent
Wang's Blog37 分钟前
Go-Zero项目开发17: IM私聊功能实现与消息存储设计
开发语言·后端·golang
IT方大同44 分钟前
C语言分支与循环语句
c语言·开发语言·算法