分布式限流要注意的问题

本文已收录至我的个人网站:程序员波特,主要记录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和连接数),将限流的上界设置在指标的「平均值」或者「中位数」附近。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在java中为什么重写equals要重写hashcode

为什么重写equals要重写hashcode 在Java中,当我们重写equals方法时,通常也需要重写hashCode方法。这是因为: 一致性:如果两个对象相等(即equals方法返回true),那么它们的哈希码(has…

Oracle AWR报告的生成和解读

Oracle AWR报告的生成和解读 一、AWR报告概念及原理 Oracle10g以后,Oracle提供了一个性能检测的工具:AWR(Automatic Workload Repository 自动工作负载库)这个工具可以自动采集Oracle运行中的负载信息,并生成与性能相…

Python 网络编程之TCP详细讲解

【一】传输层 【1】概念 传输层是OSI五层模型中的第四层,负责在网络中的两个端系统之间提供数据传输服务主要协议包括**TCP(传输控制协议)和UDP(用户数据报协议)** 【2】功能 **端到端通信:**传输层负责…

【点云、图像】学习中 常见的数学知识及其中的关系与python实操[更新中]

文章目录 前言一、平均值、方差、协方差平均值(mean)np.mean()方差(variance)np.var()总体方差 np.var(a, ddof0)无偏样本方差np.var(a, ddof1)有偏样本方差标准差(standard deviation)np.std(a, ddof1)默认…

【原创】docker +宝塔+安装zabbix

Zabbix: Zabbix可以监控各种网络服务、服务器和网络设备,而无需在目标设备上安装客户端。它的强大之处在于自带的Web界面,能够提供实时监控和各种报警功能。方法1: 步骤 创建Docker Compose文件: 首先,你需要创建一个docker-comp…

Elasticsearch Windows部署-ELK技术栈

1、下载Elasticsearch、kibana、logstash 本文不介绍ELK相关原理知识,只记录部署操作过程 下载地址Past Releases of Elastic Stack Software | Elastic 选择同一版本,这里选择是当前最新版本8.11.3 解压放在同目录下,方便后续操作与使用 …

基于Simdroid电子散热模块的电子设备机箱散热设计与优化

一、背景介绍 热设计就是通过合理的散热方式保证良好的热环境,确保电子设备可靠的工作。随着电子技术的迅速发展,电子设备的结构越来越复杂,且越来越趋于小型化,散热问题成为了影响设备可靠性的重要因素。据统计,电子…

三种引入CSS的方式

文章目录 CSS基础知识概述CSS的注释CSS的格式 三种引入CSS的方式内嵌式外链式行内式优先级 CSS基础知识 概述 Cascading Style Sheet 层叠样式表 前端三大基础之一(Html结构 CSS样式 JS动作) 最早由网景公司(Netscape)提出,在1996年受到w…

【51单片机系列】单片机与PC进行串行通信

一、单片机与PC机串行通信的设计 工业现场的测控系统中,常使用单片机进行监测点的数据采集,然后单片机通过串口与PC通信,把采集的数据串行传送到PC机上,再在PC机上进行数据处理。 PC机配置的都是RS-232标准串口,为D型…

1.15io网络

子网掩码 1.由于对于一个网络下面的主机号还是很庞大,为了进一步划分网络,我们可以将主机号再次进行划分为两部分,分别是网段号和主机号 2.此时就引入的子网掩码的概念 3. 在引入子网掩码后,IP 网络号 子网号 主机号 4.子网…

DataX数据同步(全量)

1. DataX简介 1.1 DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 源码地址:https://github.com/alibaba/Dat…

第十讲 单片机驱动彩色液晶屏 控制RA8889软件:图像运算

单片机驱动TFT彩色液晶屏系列讲座 目录 第一讲 单片机最小系统STM32F103C6T6通过RA8889驱动彩色液晶屏播放视频 第二讲 单片机最小系统STM32F103C6T6控制RA8889驱动彩色液晶屏硬件框架 第三讲 单片机驱动彩色液晶屏 控制RA8889软件:如何初始化 第四讲 单片机驱动彩色液晶屏 控…

【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

文章目录 一. “解耦”概述二. 如何给代码“解耦”?1. 封装与抽象2. 中间层2.1. 引入中间层能**简化模块或类之间的依赖关系**。2.2. 引入中间层可以起到过渡的作用,能够让开发和重构同步进行,不互相干扰。 3. 模块化4. 其他设计思想和原则4.…

[我的Rust库更新]get_local_info 0.2.3

今天收到西安城市开发者社区的文章收录通知,谢谢社区的肯定。 随即发布0.2.3版本,增加峰值算法。 get_local_info是一个获取linux本地信息的Rust三方库,其目标是降低获取本地linux系统信息的难度。支持银河麒麟10、UOS、鸿蒙等国产系统。 项…

力扣hot100 只出现一次的数字 位运算

Problem: 136. 只出现一次的数字 文章目录 思路复杂度Code 思路 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public int singleNumber(int[] nums) {int res 0;for(int x : nums)res ^ x;return res;} }

C#编程-使用反射检索元数据

使用反射检索元数据 术语反射通常用来指镜像。如果您站在镜子面前,镜子会反射出您的所有物理属性,如:您的身高、肤色和身体结构。在C#中也一样,反射被用于反射程序有关的所有信息。C#程序可以利用反射获得类在运行时的信息。 反射在运行时获取类型信息的过程中被使用。提…

C技能树-学习笔记(1-2)C语言概述和数据类型

参考:https://edu.csdn.net/skill/c 1、输出 “Hello, World!” 字符串,请选出错误答案。 2、错误的print函数。 for … in …:是python的语法,C语言的写法是for (;😉 3、C标准 没有C19标准。 4、了解C编译管道 …

实战whisper:本地化部署通用语音识别模型

前言 Whisper 是一种通用语音识别模型。它是在大量不同音频数据集上进行训练的,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别。 这里呢,我将给出我的一些代码,来帮助你尽快实现【语音转文字】的服务部署。 以下…

3.3.3 使用集线器的星形拓扑

3.3.3 使用集线器的星形拓扑 集线器的一些特点 3.3.4 以太网的信道利用率 多个站在以太网上同时工作就可能会发生碰撞当发生碰撞时,信道资源实际上是被浪费了。因此,当扣除碰撞所造成的信道损失后,以太网总的信道利用率并不能达到100% 3.…

星图地球——Landsat5_C2_SR_T1数据集

数据简介: Landsat5_C2_SR数据集是经大气校正后的地表反射率数据,属于Collection2的二级数据产品,空间分辨率为30米,基于Landsat生态系统扰动自适应处理系统(LEDAPS)(版本3.4.0)生成。水汽、臭氧、大气高度、气溶胶光学厚度、数字…