分布式限流要注意的问题

news2025/1/10 23:46:22

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。

为什么需要匀速限流

同学们回想一下在Guava小节里留的一道思考题:为什么令牌需要匀速发放?

我们做这样一个场景假设,在某个限流策略中我们设置了10r/s(每秒十个请求)的限流速率,在令牌桶算法的实现中,令牌生成器每秒会产生10个新令牌放入令牌桶。Guava的RateLimiter采用了一种“匀速”的策略生成令牌,也就是说,这10个令牌平均分到1秒钟的时间窗口中生成,每0.1秒产生一个令牌。如果在这一秒来了10个请求,这些请求会在一秒钟以内匀速消化掉。

假如我们不采用匀速发放,而是采用一把梭的模式发令牌,在每一秒开始的时候把令牌一次性发放,这样会带来什么问题呢?我们可以用两个场景来说明这种模式的弊端。

一个最明显的问题就是令牌利用率降低,比如说我在前一秒还有9个令牌,在下一秒刚开始就直接生产10个令牌,这时候令牌桶明显装不下,因此会丢弃掉9个令牌。如果在这一秒突然涌来了15个请求,由于这一秒的令牌都已经发放完毕,所以这种一把梭的发牌模式最多只能在当前时间窗口内处理10个请求,剩下的5个请求要延后到下一秒处理。而如果我们采用匀速发牌的模式,这15个请求会在下一秒的一开始就处理掉10个,剩下的请求每隔0.1秒就会获取到一个新令牌,这样一来,15个请求在一秒内就可以处理完。

除此之外,还有一个可能导致服务雪崩的问题,我们来看下面的图:
在这里插入图片描述

以上面的图为例,在00:01秒和00:02秒各有10个令牌发放。现在我化身为一个黑客,想方设法打出高额QPS (query per second)击垮后台服务,我想了这么一个方法,我专挑当前这一秒和下一秒交汇的时间发起攻击,假如在00:01秒这10个令牌没有被消耗,那么我在这一秒快结束的时候能瞬间发起10个访问。而在下一秒开始的时候由于又有10个新的令牌发放,我可以在下一秒刚到的极短时间里再发起10个访问。那么前后加起来,我可以瞬间向后台服务打出10+10=20的瞬时流量,当然20流量看起来并不大,我们如果把限流策略定为每秒1w个令牌,那么利用这种方式在理想情况下就可以打出2w的伤害,这就是一个比较可观的数字了。对于一些薄弱的后台服务,很有可能造成服务响应超时,如果发生在主链路,甚至会进一步引发服务雪崩。

基于上面这些情况,我们才需要将令牌按照一个“匀速”的频率放进令牌桶。除此之外,也可以利用前面提到的”滑动窗口“算法,尽量使流量平滑输出,不过即便是滑动窗口也并不能保证不会出现上面提到的人造流量峰值攻击,所以,使用匀速令牌桶才是理想的方案

限流组件的失效

常在河边走,哪有不湿鞋,再牛的系统也不能保证100%的可用性,限流组件也不意外。尽管Redis和Nginx都是蛮靠谱的组件,但是明天和意外你永远不知道哪一个先来,珍惜当下的同时,对限流组件失效的情况,我们应该怎么办?

这是一个悖论似的问题,继续提供服务就相当于给了外部攻击者利用流量洪峰击垮系统的机会,而拒绝服务就相当于系统关门打烊了。我们可以参考SpringCloud和其他限流开源方案的做法,当限流组件失效的时候,默认不启用限流服务。比如Spring CloudGateway网关默认提供了Lua+Redis的限流功能,当Redis服务不可用的时候,Gateway就直接将所有访问请求做放行处理。

其实道理很简单,拒绝外部请求所造成的损失,远大于放行请求暴露出的潜在破绽。大家在设计自己的限流方案的同时,一定要记得考虑异常情况,如果是限流组件自身不可用的问题,那么就放弃限流,选择直接放行服务。

架构思考-如何确定限流上界

对限流组件来说,如果能“卡在”系统处理能力的上限附近,那是再好不过的了。因此这个数值不能靠猜,而必须基于事实依据。那么事实从哪里来?压力测试!

在历次阿里集团双11的大运动中,其实早在双11前半年,很多业务部门已经开始在为双11做技术优化了。在双11之前的几个月,全面压测已经在集团的全链路压测平台上紧锣密鼓的开展了。当然,压测和容灾演练在平时空闲的时候也会开展,对于我们这更像是一个“常态化”的过程,就比如集团经常冷不丁切断一个机房的设备,倒逼各个事业部将各自的应用以异地多活的方式部署。

压测不仅仅是无脑打高流量,找到系统的极限,而是在基于一个合理的“预估”访问量级之下,对系统进行全方位的摸底。执行全链路压测,它不仅包含压力测试,还有故障演练,异地多活演练(突然切断一整个机房),弹性伸缩(紧急上线新机器提高算力),服务降级(核心主链路降级演练,考察系统的最低可用性)等等复杂的流程。

因此,在确定限流上界之前,我们要根据当前业务规模预估一个合理的访问量级,再乘以一个系数(比如1.2)保证当前系统有一部分设计余量(预留少量弹性空间),通过压测找到系统瓶颈加以巩固,先确保当前系统在这个量级下的可用性。在此之上,向上打流量,反复进行多次测试后分析汇总性能指标(QPS和连接数),将限流的上界设置在指标的「平均值」或者「中位数」附近。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1388463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何部署Wagtail CMS并结合cpolar内网穿透实现远程访问管理界面

文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 前言 Wagtail是一个用Python编写的开源CMS,建立在Django Web框架上。Wagtail 是一个基于 Django 的开源内容管理系统&#xf…

电商新趋势:解析养号的必要性及海外云手机运用攻略

在电商领域,什么最为关键?答案无疑是流量!然而,如何以较低成本获取大量流量成为了许多电商从业者头疼的问题。虽然直接投放广告是一种方式,但在内卷的情况下效果越来越难以令人满意,高昂的广告费用也原来越…

编译与链接(C/C++)

在C/C中关于代码的运行需要经过.c文件到.exe文件,而其中走过这些步骤这需要对原始的.c文件进行编译与链接。对于编译与链接主要构成了翻译环境,经过翻译环境之后生成.exe文件,然后在通过运行环境输出对应的结果。本篇主要讲解编译与链接。 以…

动手搓一个kubernetes管理平台(1)-需求和框架

先拍个脑袋 市面上对于kubernetes集群的管理平台其实不算少,但常用的就那么几个,比如厚重的rancher,比如老而弥坚的kube-dashboard,以及集成了很多其他功能的kubeSphere等,但和其他开源项目一样,为了满足大…

火爆!大厂流出的接口版本号规约,速度收藏

在实际项目开发中,API的版本号控制不仅仅是一个数字游戏,它的使用需遵循语义版本控制(Semantic Versioning)原则,确保代码的每一次更改都能通过版本号的变化得到准确的体现,本篇文章对版本号如何使用做了详…

八款常用uml用例图-画图干货

随着软件开发和系统设计的复杂度不断提升,UML已经成为业界标准。UML用例图作为其中一种重要图表,能够清晰地展示系统功能和用户需求。本文将为你介绍八款常用的UML用例图,助你轻松搞定画图难题! 一、费用报销系统UML用例图 二、登…

使用vite框架封装vue3插件,发布到npm

目录 一、vue环境搭建 1、创建App.vue 2、修改main.ts 3、修改vite.config.ts 二、插件配置 1、创建插件 2、开发调试 3、打包配置 4、package.json文件配置 上一篇文章讲述使用vite《如何使用vite框架封装一个js库,并发布npm包》封装js库,本文将…

Qt中QGraphicsView架构下实时鼠标绘制图形

上一章节介绍了关于QGraphicsView的基础讲解,以及简单的类图创建,由上一章节中最后展示的动画效果来看,今年主要讲述如何在QGraphicsView架构下,实时拖动鼠标绘制图形! 今天主要以矩形为例,再来看一下展示…

通过浏览器URL地址,5分钟内渗透你的网站!很刑很可拷!

今天我来带大家简单渗透一个小破站,通过这个案例,让你深入了解为什么很多公司都需要紧急修复各个中间件的漏洞以及进行URL解析拦截等重要操作。这些措施的目的是为了保护网站和系统的安全性。如果不及时升级和修复漏洞,你就等着被黑客攻击吧&…

SAP不同语言开发

文章目录 1 Please write English Nmae2 go to goto menu and translation3 Write your target language .4 Please input Chinese5 Summary 1 Please write English Nmae 2 go to goto menu and translation 3 Write your target language . 4 Please input Chinese 5 Summary…

【Docker】Docker基础教程

🦖我是Sam9029,一个前端 🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍 基…

Unity中URP下的SimpleLit顶点着色器

文章目录 前言顶点着色器1、GPU Instance 相关2、顶点输入数据相关3、雾效混合因子4、对 uv 进行 Tilling 和 Offset 的应用 及 把顶点的坐标信息传给输出结构体5、把法线相关的结果,传给输出结构体6、光照贴图相关7、额外灯相关计算8、阴影相关 前言 在上一篇文章…

Vue项目中如何解决跨域详解

文章目录 一、跨域是什么二、如何解决CORSProxy方案一方案二方案三 一、跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能 所谓同源&#x…

easyMarkets易信是一家靠谱的外汇平台吗 ?FX110汇评

今天小编就带大家全面了解一下老牌优质交易商easyMarkets 易信。在FX110网首页搜索“easyMarkets 易信”进入交易商详情页。 查看FX110官网的交易商详细数据可以发现,easyMarkets 易信在FX110上的交易商评分为83.8分,牌照评级AA级,口碑打分4.…

基于YOLOv7的学生课堂行为检测,引入BRA注意力和多种IoU改进提升检测能力

💡💡💡本文摘要:介绍了学生课堂行为检测,并使用YOLOv7进行训练模型,以及引入BRA注意力和多种IoU改进来提升检测能力 目录 1.SCB介绍 ​编辑 2.如何提高YOLOv7课堂行为检测能力 2.1 训练基于YOLOv7模型的…

【数据库原理】(27)数据库恢复

在数据库系统中,恢复是指在发生某种故障导致数据库数据不再正确时,将数据库恢复到已知正确的某一状态的过程。数据库故障可能由多种原因引起,包括硬件故障、软件错误、操作员失误以及恶意破坏。为了确保数据库的安全性和完整性,数…

类和对象特性

#include<iostream> #include<string> using namespace std; class peron{ public:peron(string person){cout << "peron调用构造函数" << endl;tperson person;}~peron(){cout << "peron调用析构函数" << endl;}//手…

【书生·浦语】大模型实战营——第五次课程作业

基础作业——使用LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署InternLM-Chat-7B模型&#xff0c;生成300字的小故事 环境准备 除了安装所需依赖之后&#xff0c;重要的是进行模型转化&#xff08;转换成TurboMind格式&#xff09;&#xff0c;这里需要注意转化命…

连接器应用案例详解 | prodesign加速卡采用Samtec NovaRay® 极高密度阵列

【摘要/前言】 ChatGPT最近受到的欢迎和关注凸显了人工智能在影响日常生活方面所取得的进展。 有谁曾使用 ChatGPT 完成家庭作业或撰写博客&#xff1f;提前申明&#xff1a;这一篇文章绝对是真人撰写~ 无论如何&#xff0c;像ChatGPT这样的聊天机器人和类似服务的支柱都是高…

如何更改路由器Wi-Fi密码,这里提供通用步骤

这篇文章解释了如何通过路由器的设置更改Wi-Fi密码&#xff0c;即使你不知道当前的密码。 如何更改你的Wi-Fi密码 该过程按照以下一般步骤展开。 ​重要&#xff1a;这些是更改Wi-Fi密码的通用说明。更改路由器设置所需的步骤因不同制造商的路由器而异&#xff0c;甚至可能在…