分享好友 站长动态首页 网站导航

限流接法原理

网友发布 2022-08-13 16:53 · 头闻号项目分享

在高并发系统中,我们通常需要通过缓存、降级和限流等多种方式来提供系统的可用性。本文将详细解释应用中常用的限流算法。

简介

流量限制(flow rate limit)的简称,流量限制是指只允许指定的事件进入系统,超出部分将被拒绝服务、排队或等待、降级等处理。常见的流量限制方案如下:

固定时间窗口

固定时间窗是最常见的限流算法之一。窗口的概念对应的是限流场景中的限流时间单位。

原则

时间线被分成多个大小固定独立窗口;

落在每个时间窗口内的请求使计数器增加1;

如果计数器超过当前限制阈值,则落入该窗口的后续请求将被拒绝。但是当时间到达下一个时间窗口时,计数器将被重置为0。

说明

注意:在上面显示的场景中,电流被限制为每秒10次,窗口大小为1秒。每个方块代表一个请求,绿色方块代表一个正常的请求,红色方法代表一个受限的请求。在每秒10次的场景下,从左向右看,输入10个请求后,后面的请求会受到限制。

优点和缺点

优势

逻辑简单,维护成本低;

劣势

切换车窗时,不能保证电流限值。

相关实施

固定时间窗的具体实现可以通过Redis调用lua限流脚本来实现。

限流脚本

具体实现

试验

注意:该测试每3秒访问一次,超过时会提示错误。

滑动时间窗口

滑动窗口算法是固定窗口算法的改进。在滑动窗口算法中,还需要根据当前请求动态查询窗口。但是窗口中的每个元素都是子窗口。子窗口的概念类似于第一种方案中的固定窗口,子窗口的大小可以动态调整。

实现原则

单位时间分为几个区间,一般分为几个小时间段;

每个区间都有一个计数器。如果请求落在此间隔内,此间隔内的计数器将增加1。

在每个时间段之后,时间窗口将向右滑动一个网格,丢弃最老的间隔并将其带入新的间隔;

在计算整个时间窗口内的请求总数时,所有时间段内的计数器都将累加。如果总计数超过限制数,此窗口中的所有请求都将被丢弃。

说明

注意:比如上图中的场景是每分钟限流100次。每个子窗口的时间维度设置为1秒,因此一分钟的窗口有60个子窗口。每当这样的请求到来,我们动态计算这个窗口的时候,最多需要寻找60次。时间的复杂度从线性变成了常数,时间的复杂度会相对低一些。

具体实现

至于滑动时间窗的实现,可以使用sentinel,后面会详细讲解sentinel的使用方法。

漏桶

漏桶水首先进入漏桶,然后漏桶以一定的速度流出。当进水大于出水时,多余的水直接溢出。当请求替换为水时,漏桶相当于服务器队列,但当请求量大于当前限制阈值时,多余的请求将被拒绝服务。通过使用漏桶队列,可以将业务的访问速度控制在一个固定的速率上,并且可以对业务进行分级。

原则

描述:

将每个请求放在固定大小的队列中等待处理。

队列以固定的速率流出请求,如果队列为空,则停止流出。

如果队列已满,多余的请求将被直接拒绝。

具体实现

令牌桶算法

令牌桶算法是基于漏桶的改进版本。在令牌桶中,令牌代表当前系统允许的请求上限,令牌将以统一的速度放入桶中。当桶满时,新令牌被丢弃。

原则

令牌以固定速率生成,并放入令牌桶;

如果令牌桶已满,多余的令牌将被直接丢弃。当请求到达时,将从令牌桶中提取令牌,并且可以执行已经获得令牌的请求。

如果bucket 空用完了,请求就会被拒绝。

具体实现

执行结果:

解释:接口被限制为每2秒一个请求,需要10个线程20秒来完成处理。但是,rateLimiter.tryAcquire限制在10秒钟内没有获得令牌的情况下抛出异常,因此5个结果将被频繁请求。

总结

固定窗口:实现简单,适用于流量分布比较均匀,限流精度要求不高的场景。

滑动窗口:适用于对精度和性能有一定要求的场景,可以调整子窗口数量来权衡性能和精度。

漏桶:适用于交通绝对畅通的场景。

令牌桶:适用于整体流畅的流量,也可以满足一定的突发流程场景。

摘要

本文详细阐述了几种限流算法的原理和实现。如果您有任何问题,请随时反馈。

作者:大剑师无痕

链接:file/tupian/20220813/p

免责声明:本平台仅供信息发布交流之途,请谨慎判断信息真伪。如遇虚假诈骗信息,请立即举报

举报
反对 0
打赏 0
更多相关文章

评论

0

收藏

点赞