首页 > 编程语言 >限流算法

限流算法

时间:2024-07-05 13:55:13浏览次数:11  
标签:令牌 请求 算法 限流 漏桶 1000

限流的手段通常有计数器、漏桶、令牌桶。注意限流和限速(所有请求都会处理)的差别,视业务场景而定。
(1)计数器:
在一段时间间隔内(时间窗/时间区间),处理请求的最大数量固定,超过部分不做处理。
(2)漏桶:
漏桶大小固定,处理速度固定,但请求进入速度不固定(在突发情况请求过多时,会丢弃过多的请求)。
(3)令牌桶:
令牌桶的大小固定,令牌的产生速度固定,但是消耗令牌(即请求)速度不固定(可以应对一些某些时间请求过多的情况);每个请求都会从令牌桶中取出令牌,如果没有令牌则丢弃该次请求。

计数

在一段时间间隔内(时间窗/时间区间),处理请求的最大数量固定,超过部分不做处理。

简单粗暴,比如指定线程池大小,指定数据库连接池大小、nginx连接数等,这都属于计数器算法。

计数器算法是限流算法里最简单也是最容易实现的一种算法。

举个例子,比如我们规定对于A接口,我们1分钟的访问次数不能超过100个。

那么我们可以这么做:

  • 在一开 始的时候,我们可以设置一个计数器counter,每当一个请求过来的时候,counter就加1,如果counter的值大于100并且该请求与第一个请求的间隔时间还在1分钟之内,那么说明请求数过多,拒绝访问;

  • 如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置 counter,就是这么简单粗暴。

img

 

缺点

这个算法虽然简单,但是有一个十分致命的问题,那就是临界问题,我们看下图:
img

从上图中我们可以看到,假设有一个恶意用户,他在59分时,瞬间发送了100个请求,并且1时又瞬间发送了100个请求,那么其实这个用户在1分钟里面,瞬间发送了200个请求。

我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求, 可以瞬间超过我们的速率限制。

用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。

漏桶

漏桶算法限流的基本原理为:水(对应请求)从进水口进入到漏桶里,漏桶以一定的速度出水(请求放行),当水流入速度过大,桶内的总水量大于桶容量会直接溢出,请求被拒绝。
大致的漏桶限流规则如下:
(1)进水口(对应客户端请求)以任意速率流入进入漏桶。
(2)漏桶的容量是固定的,出水(放行)速率也是固定的。
(3)漏桶容量是不变的,如果处理速度太慢,桶内水量会超出了桶的容量,则后面流入的水滴会溢出,表示请求拒绝。

缺点

  • 无法面对突发的大流量—>比如请求速率为1000/s,容量为5000,来了一波2000/s的请求持续10s,那么后5s的请求将全部直接被丢弃,服务器拒绝服务,但是实际上网络中突发一波大流量尤其是短时间的大流量是非常正常的。
  • 无法有效利用网络资源—>比如虽然服务器的处理能力是1000/s,但这不是绝对的,这个1000只是一个宏观服务器处理能力的数据,实际上一共5秒,每秒请求量分别为1200、1300、500、800、平均下来QPS也是1000/s,但是这个量对服务器来说完全是可以接受的,但是因为限制了速率是1000/s,因此前面的3秒,每秒只能处理掉1000个请求而一共打回了700个请求,白白浪费了服务器资源

令牌桶

令牌桶算法以一个设定的速率产生令牌并放入令牌桶,每次用户请求都得申请令牌,如果令牌不足,则拒绝请求。
令牌桶算法中新请求到来时会从桶里拿走一个令牌,如果桶内没有令牌可拿,就拒绝服务。当然,令牌的数量也是有上限的。令牌的数量与时间和发放速率强相关,时间流逝的时间越长,会不断往桶里加入越多的令牌,如果令牌发放的速度比申请速度快,令牌桶会放满令牌,直到令牌占满整个令牌桶,如图所示。

令牌桶限流大致的规则如下:
(1)进水口按照某个速度,向桶中放入令牌。
(2)令牌的容量是固定的,但是放行的速度不是固定的,只要桶中还有剩余令牌,一旦请求过来就能申请成功,然后放行。
(3)如果令牌的发放速度,慢于请求到来速度,桶内就无牌可领,请求就会被拒绝。

总之,令牌的放置速率可以设置,从而可以对突发的出口流量进行有效的应对。

为什么令牌桶算法可以防止一定程度的突发流量?

假设我们想要的速率是1000Qps,那么往桶中放令牌的速度就是1000个/s,假设第1秒只有800个请求,那么意味着第2秒可以容许1200个请求,这就是一定程度突发流量的意思,反之我们看漏桶算法,第1秒只要800个请求,那么全部放过,第2秒这1200个请求将会被打回200个。

注意上面多次提到一定程度这四个字,这也是我认为令牌桶算法最需要注意的一个点。假设还是1000QPS的速率,那么每秒钟放1000个令牌,第1秒钟800个请求过来,第2~4秒没有请求,那么按照令牌桶算法,第5秒钟可以接受4200个请求,但是实际上这已经远远超出了系统的承载能力,因此使用令牌桶算法特别注意设置桶中令牌的上限。

区别

漏桶算法与令牌桶算法的区别在于,漏桶算法能够强行限制数据的传输速率,令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。

标签:令牌,请求,算法,限流,漏桶,1000
From: https://www.cnblogs.com/zhengbiyu/p/18285647

相关文章

  • 代码随想录算法训练营第十四天| 226.翻转二叉树 、101. 对称二叉树、104.二叉树的最大
    二叉树学习2226题翻转二叉树,改一下前序递归遍历,每次遍历的时候都调换一下左右结点即可。classSolution{public:voidpreorder(TreeNode*root){if(root==nullptr){return;}TreeNode*tmp;tmp=root->left;......
  • 算法:递归数组求和
    递归数组求和给定一个数组,求所有元素的和算法思想:传入数组和下标,如果下标越界就返回0,否则返回当前值和下一个值的和,递归操作。Java实现:publicclassMain{ publicstaticintfunc(int[]array,intindex){ if(index>array.length-1){ return0; }el......
  • 代码随想录算法训练营第十三天|今天量大管饱144、145、94、102、107、199、637、429、
    今天来处理二叉树part1、2、3,顶级享受,一次到位。完全二叉树和满二叉树概念没问题。二叉搜索树,左子树所有结点的值小于它的根结点的值,右子树上所有结点的值大于它的根结点的值平衡二叉搜索树,它是一棵空树或它的左右两个子树的高度差的绝对值不超过1。二叉树的存储方式:链式存储......
  • 「代码随想录算法训练营」第三天 | 链表 part1
    203.移除链表元素题目链接:https://leetcode.cn/problems/remove-linked-list-elements/题目难度:简单文章讲解:https://programmercarl.com/0203.移除链表元素.html视频讲解:https://www.bilibili.com/video/BV18B4y1s7R9题目状态:通过个人思路:从链表头部开始依次往下遍历,当......
  • 算法学习笔记(24):卡常小技巧
    卡常学习来源->https://platelet.top/hpc/oldst表访问连续性就不说了,考虑计算log2。预处理比31^builtin__clz(x)慢,而且慢很多。setinsert(pos,x)如果\(pos\)是\(x\)在set中正确的位置,那么insert是\(O(1)\)的。erase(it)是\(O(1)\)的。prev(it)......
  • 智能分析网关V4人员区域徘徊AI检测:算法原理介绍及技术应用场景
    一、引言在现代社会,随着科技的不断发展,视频监控系统已广泛应用于各个领域,如公共安全、商业管理、交通监控等。其中,区域徘徊检测算法作为一种重要的视频分析技术,能够有效地识别出特定区域内人员的徘徊行为,为安全管理和事件预防提供了有力支持。本文将以TSINGSEE青犀AI智能分析网关......
  • 人员跌倒识别检测算法
    人员跌倒识别检测算法是基于视频的检测方法,通过对目标人体监测,当目标人体出现突然倒地行为时,自动监测并触发报警。人员跌倒识别检测算法基于计算机识别技术,配合现场摄像头,自动识别如地铁手扶梯/楼梯、老幼活动区等公共场所人员摔倒行为,准确率高于90%,及时救援,提高人工监管效果,保障......
  • 安全帽佩戴检测算法
    安全帽佩戴检测算法是铁路工程施工人员安全管理中的重点和难点,它对检测算法的准确率与检测速度都有较高的要求。本文提出一种基于神经网络架构搜索的安全帽佩戴检测算法NAS-YOLO。该神经网络架构由上、下行操作单元组成,采用二进制门策略对网络架构进行更新,通过数据驱动的方式自......
  • 雪花算法
    雪花算法1.1概述雪花算法是twitter开源的一个分布式id的生成算法。雪花id,是分布式计算中使用的唯一标识符的一种形式。该格式由twitter创建。人们普遍认为,每片雪花都有唯一的结构,因此他们取了“雪花ID”这个名字。1.2什么是雪花id雪花id是有一种分布式id算法生成的,他的设计......
  • 代码随想录算法训练营第五十天 | 1143.最长公共子序列 392.判断子序列
    1143.最长公共子序列题目链接文章讲解视频讲解dp[i][j]:表示以text1以i-1为结尾text2以j-1为结尾的最长公共子序列为dp[i][j]递推公式:如果text1[i-1]==text2[j-1]那么dp[i][j]=dp[i-1][j-1]+1;  如果不相同的话,那么dp[i][j]=max(dp[i-1][j],dp[i][j-1]);cl......