瞬时流量过高,服务被压垮?恶意用户高频光顾,导致服务器宕机?消息消费过快,导致数据库压力过大,性能下降甚至崩溃?
在高并发系统中,出于系统保护角度考虑,通常会对流量进行限流;不但在工作中要频繁使用,而且也是面试中的高频考点。
今天我们将图文并茂地对常见的限流算法分别进行介绍,通过各个算法的特点,给出限流算法选型的一些建议,并给出Java语言实现的代码示例。
01 固定窗口
固定窗口又称固定窗口(又称计数器算法,Fixed Window)限流算法,是最简单的限流算法,通过在单位时间内维护的计数器来控制该时间单位内的最大访问量。
假设限制每分钟请求量不超过60,设置一个计数器,当请求到达时如果计数器到达阈值,则拒绝请求,否则计数器加1;每分钟重置计数器为0。代码实现如下:
public class CounterRateLimiter extends MyRateLimiter { /** * 每秒限制请求数 */ private final long permitsPerSecond; /** * 上一个窗口的开始时间 */ public long timestamp = System.currentTimeMillis(); /** * 计数器 */ private int counter; public CounterRateLimiter(long permitsPerSecond) { this.permitsPerSecond = permitsPerSecond; } @Override public synchronized boolean tryAcquire() { long now = System.currentTimeMillis(); // 窗口内请求数量小于阈值,更新计数放行,否则拒绝请求 if (now - timestamp