KLimiter自适应限流器
通常情况下,我们对下游资源(如db)的保护,是通过对上游接口限流进行的;多个接口的峰值时间点按约定错峰,并给予一定流量限制,可以保护下游资源在安全水位内。
这种做法有以下缺点:
-
随着业务迭代,上游接口接入方越来越多,形形色色的接口也越开越多,这就导致上游接口的峰值时间错中复杂,难以评估;
-
上游接口的峰值时间有时候是由口头/书面约定而成,没有强制的系统制约,这就导致多个接口峰值可能会出现如下叠加情况,最终让下游资源水位超过安全阈值。
-
为了避免问题2的出现,多数系统的做法是将上游接口的限流阈值设置得更低或是对下游资源进行扩容,来保障下游水位安全;但是这种做法又会导致下游长期的资源浪费。
所以,本文实现了一种限流工具,能够基于下游资源的水位自适应调节上游接口流量;即保护的是下游资源水位,但是保护的方式是调节影响该资源的上游接口流量。
![]()
介绍
KLimiter为了实现上述诉求,并且支持不同入口优先级不同,本文的限流工具有如下能力:
-
秒级监测多个下游资源的水位;
-
自适应调节多个入口的流量,将下游资源水位维持在阈值之下;
-
多个入口可设置不同的优先级,优先降低低优先级的入口流量到一定比例。
![]()
概要设计
▐ 限流方案
基于流量比例进行限流,比如另入口流量比例为70%,那么将阻断30%的请求。
▐ 名词解释
名词 | 解释 | 例子 |
限流入口 | 需要限制流量的入口 | 如【查询xxx的接口】就是一个限流入口 |
资源基线 | 自适应限流需要关注的下游资源实例;基线包含名称和其水位值 | 如【 xx库】就是一个资源基线,本文用xx库的操作qps来描述其水位值 |
入口影响的基线 | 限流入口会影响资源基线 | 如【xx接口】,会影响到【aa库】【bb库】这两个基线的水位 |
影响系数 | 一个基线可能由多个限流入口影响,不同的入口在不同的时刻,对基线影响的占比是不一样的,这个占比进行归一化后叫做影响系数 | 如【 aa库】会由【xx接口】、【yy接口】等多个入口影响,某个时刻,一次【xx接口】请求对【 aa库】贡献1qps,一次【yy接口】请求对【 aa库】贡献3qps,则【xx接口】影响系数为0.25,【yy接口】影响系数为0.75;这个影响系数在按优先级调流时会用到 |
流量比例 | 本文通过限制入口的流量比例来实现限流,而不是限制一个具体的qps值 | |
入口优先级 | 本文入口优先级,定义为期望该入口最多能降低到的流量比例 |
▐ 设计图解
-
调流原理
如图,本文自适应限流器会优先保证入口流量高于其设置的优先级阈值,如果该入口不能再降低流量了,会先降低其他优先级更低的入口流量。如step1中,入口3的流量比例降低到优先级阈值就不能再降了,在step2会让入口1和入口2去降低原本应该由入口3降低的流量比例。
如果所有入口的流量比例均到了优先级的阈值:
则会进行第二轮调流,第二轮会一视同仁,所有入口一起降。
-
代码模块
如图,一个限流入口会影响多个资源基线,一个资源基线也会被多个限流入口影响;自适应限流器有2个后台线程,分别用于统计qps和计算入口的流量比例:
-
qps采集线程:每1s执行一次,遍历所有入口和基线,计算过去1s的qps值;
-
流量比例调节线程:每5s执行一次,基于6.1算法重新计算所有入口的影响系数,基于6.2、6.3算法重新计算所有入口的流量比例。
挑战
1、多个入口需要有限流的优先级,比如入口A最多降到90%流量比例,入口B最多降到70%流量比例,入口C可以降到0;假设基线期望降低10%的流量,理论上A、B、C均降低10%即可,但如果A流量比例已经是90%了,那么原本应该由A降低的这部分流量,需要由其它入口承担降低(其它入口要降低更多的流量),那么其他入口需要降低多少流量呢,这个比例需要怎么折算?
2、要解决1,需要引入影响系数,不同的入口对基线的影响系数是不一样的,假设A系数是0.4,B系数是0.3,C系数是0.3,那么B、C在降低了原本应该降低的10%流量后,基线还需要降低0.4 * 10%的水位;但是不同时间、不同入口的影响系数必然是在变化的,这个系数如何计算呢?
3、影响系数确定后,基线需要降低的流量比例确认后,多个入口在优先级的限制下,最终每个入口需要降低多少流量比例,这个如何计算呢?
本文设计核心即解决以上三个挑战。
▐ 限流入口系数求解
对于某个资源基线,我们以如下流程计算其入口在该资源基线下的影响系数。
假设有n个入口,共同影响资源基线y,我们可以知道这n个入口的qps
,以及这个资源基线的水位L,就可以得出以下方程:
由于入口流量都为0的时候,基线水位L也为0,所以 C=0,即得到:
其中为n个入口的影响系数;可见,要得到这n个影响系数,需要n个这样的方程;
基于历史采样信息,我们可以获得过去的n个时刻的qps矩阵:
令影响系数为:
令历史n个时刻的基线水位为:
最终可以得到历史n个时刻的入口qps和水位关系的方程组:
其为n元1次方程组,基于LU分解法(高斯消元法复杂度,LU分解法复杂度
, 故选择LU分解法求解)即可求出
,最终对它们进行归一化,这里的归一化并非向量的归一化,而是最终描述各个入口占所有入口对基线的影响比例:
上述方法即可得出最终的影响系数;
由于LU分解本质是高斯消元法,需要矩阵A正定,否则无解;另外为负数的解也是没有实际意义的,所以需要讨论劣化场景。
当矩阵非正定,或求出的解为负数时,方程是无解或解是无意义的,此时可以将问题转换为优化问题,令
由于是单调的,所以可以用牛顿迭代法(Newton-Raphson)求最接近初始值近似,第k次迭代结果为:
这里用于控制
均大于0,若无法满足,则停止迭代;
迭代初始值的选取为上一轮流量调控计算的系数结果,即让本次优化结果更接近于上一轮计算值。为了减少0值的影响,上一轮计算结果为0的,本轮初始值赋1。
▐ 流量降低算法
本文对入口定义的优先级,为期望该入口最多能降低到的流量比例。
令基线当前水位为,期望的阈值水位为
,则可以得到基线需要降低流量比例为:
令当前n个入口的流量比例为
,假设不降低流量的qps为
,系数为
,即有
基线水位降低比例,则最终期望的基线水位为
,即有
于是有入口的期望流量比例
为
即需要降低的流量比例为
假设入口当前最多只能降低
的流量比例,那么我们可以认为原本应该由a_i降低的流量比例:
需要在下一轮的流量降低调整中,由其他入口进行调整;下一轮的流量调整中,基线还需要降低的流量比例为:
简单描述这个公式,即原本应该由降低的流量比例在其当前流量比例的占比,再乘上当前入口在所有入口中的影响比例,得到这次原本应该由
降低的流量比例对基线水位比例的影响,这部分流量调整在下一轮中由其他入口承担。
▐ 流量提高算法
流量提高是站在入口视角来看的,入口的其中一个基线可以提升的倍数为,那么这个基线允许入口增加的流量比例为
一个入口影响的基线可能有多个,最终选取能够提升得最小的一个值。
▐ 一些兜底策略
-
跌零保护
-
降低流量速率
-
慢启动
-
波动影响
效果
ob基线水位阈值设置为60,入口1优先级为0%,入口2优先级为50%;可见入口2比例到50%后不再降低,只降低入口1;入口1降到0依然不满足,最终入口2也降低到30%左右,保持ob基线水位在60左右。
ob基线阈值回调到100,可见入口流量比例也回升,保持ob基线水位在100左右。
结语
参考资料
-
《奇异矩阵定义》:
https://zhuanlan.zhihu.com/p/662240649
-
《LU分解解线性方程组》:
https://zhuanlan.zhihu.com/p/386954541
-
《高斯消元解线性方程组》:
https://wuli.wiki/online/GAUSS.html
-
《浅说 Newton-Raphson 方法》
https://zhuanlan.zhihu.com/p/696670386
本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
希望成为一名 API 安全专家吗?
原文作者:Byron McNaught - F5 高级解决方案营销经理 原文链接: 希望成为一名 API 安全专家吗? 转载来源: The New Stack NGINX 唯一中文官方社区 ,尽在 nginx.org.cn阅读原文。 中国名将孙武在其兵书典著《孙子兵法》中说道:“知彼知己,百战不殆。”就网络安全而言,他的下一句话更为重要:“知己而不知彼,一胜一负。” 简而言之,要想了解您的敌人,您必须先成为自己的敌人。 安全专家深知维护 API 清单、及时了解风险态势的持续变化以及监控潜在安全风险的重要性。但是,要真正成为 API 安全专家,您需要从攻击者的角度思考,预测战术和技术,并制定安全防御措施来降低风险。 OWASP 开放式WEB应用安全项目 (OWASP) 是一个致力于提高软件安全性的非营利性基金会,其标志性项目是 OWASP 十大 Web 应用安全风险列表。OWASP 还发布了一份十大 API 安全风险列表,列出了应用编程接口 (API) 面临的独特安全风险。 下面让我们详细了解一下在威胁建模过程中需要考虑的主要 API 安全防护风险: 图 1 — OWASP 十大 AP...
- 下一篇
通过MySQL Workbench 将 SQL Server 迁移到GreatSQL
通过MySQL Workbench 将 SQL Server 迁移到GreatSQL 一、概述 MySQL Workbench 提供了可以将Microsoft SQL Server的表结构和数据迁移到 GreatSQL 的功能,此次将通过MySQL Workbench将SQL Server的数据迁移到GreatSQL。 本文章只是简单演示一下单张表的迁移,如果在项目中使用请根据实际情况进行调整。 二、风险评估 1.数据类型不匹配 两种数据库系统的数据类型可能不完全兼容。在迁移过程中,需要确保数据在不同类型之间的正确转换,否则可能导致数据丢失或不准确。 下表显示了Microsoft SQL Server(源)数据类型和GreatSQL数据类型之间的映射。 Microsoft SQL Server Type GreatSQL Type Comment INT INT TINYINT TINYINT UNSIGNED flag set in MySQL. SMALLINT SMALLINT BIGINT BIGINT BIT TINYINT(1) FLOAT FLOAT Precision ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能