服务限流作用及限流算法 | 8月更文挑战
限流作用
限流目的是通过限制并发访问数或者限制一个时间窗口允许处理的请求数量来保护系统。
当系统请求数达到限制数量则对当前请求进行处理采取对应的拒绝策略,如跳转错误页面
限流的主要作用是损失一部分用户的可用性。
限流应用实际开发场景:
- 在nginx层添加限流模块限制平均访问速度
- 设置数据库连接池,通过线程池的大小来限制总的并发数
- TCP通信协议中的流程整形
- 通过Guava提供的Ratelimiter限制接口的访问速度
限流实现(限流算法)
-
计数器算法
简单的限流实现算法,在指定周期内累加访问次数,当访问次数达到阈值时,触发限流策略,当进入下一个时间周期时重置访问次数。这种算法用在短信发送的频次限制,比如限制同一个用户一分钟之内触发短信发送的次数。不足之处存在临界问题。
一秒出现等于阈值的请求数
-
滑动窗口算法
为了解决计算器算法带来的临界问题,引入滑动窗口算法。
滑动窗口算法原理:在固定窗口中分割出多个小时窗口,分别在每个小时间窗口中记录访问次数,然后根据时间将窗口往前滑动并删除过期的小时间窗口,最终只需统计滑动窗口范围内的所有小时间窗口总的计数即可。
将一分钟拆分为4个小时间窗口,每个小时间窗口最多能够处理25个请求,并且通过滑动窗口大小(当前窗口大小是2,也就是最多能处理50个请求)。同时滑动窗口会随着时间往前移动,比如前面15s结束后,窗口会滑动到15s-45s范围,在新的窗口中重新统计数据。这种方式能解决了固定窗口算法的临界问题。
Sentinel就是采用滑动窗口算法来实现限流
-
令牌桶限制算法
令牌桶是网络流量整形和速率限制中最常使用的算法,对于每一个请求,都需要从令牌桶中获取一个令牌,如果没有获取令牌,则需要触发限流策略。
系统以恒定速度往固定容量的令牌桶中放入令牌,如果此时有客户端请求,则需要从令牌桶获取令牌以获取访问资格。
假设令牌生成速度是每秒10个,等同于QPS=10,
在请求获取令牌时,存在以下情况:
-
请求速度大于令牌生成速度,令牌很快被获取完,后续请求会被限流
-
请求速度等于令牌生成速度,流程处于稳定状态
-
请求速度小于令牌生成速度,说明系统的并发数不高,请求能被正常处理。
令牌桶特性:
令牌桶有固定的大小,令牌桶被填满后,令牌会被丢弃,短时间内新增的流量系统能够正常处理
-
-
漏桶限流算法
漏桶限流算法的主要作用是控制数据注入网络的速度,平滑网络上的突发流量。
在漏桶算法内部维护一个容器,容器以恒定速度出水,不管请求数多大,漏桶水滴的流出速度始终保持不变,实际上消费中间件就是使用了漏洞限流的思想,不管生产者生产消息多少,消息的处理取决于消费者。
在漏桶限流算法中,存在以下情况:
-
请求速度大于漏桶出水滴的速度,请求数超出当前服务所能处理的极限,会触发限流策略。
-
请求速度小于或者等于漏桶出水滴的速度,服务端的处理能力刚好满足客户端的请求量,将正常执行
漏桶限流算法和令牌桶限流算法的区别是漏桶无法处理短时间的突发流量,漏桶限流算法是一种恒定速度的限流算法。