参考:精确掌控并发:分布式环境下并发流量控制的设计与实现(一)-CSDN博客
滑动窗口算法是一种更为灵活的流量控制方案,它比固定窗口算法能更平滑地处理突发流量。在滑动窗口中,时间窗口是重叠的,这意味着流量的计算是基于过去的一段连续时间内发生的事件。
工作流程:
实现细节:
滑动窗口可以通过队列或循环数组来实现。每个窗口对应队列中的一个元素,记录该窗口期间的请求数。当时间滑动时,更新队列头部的元素,并可能将旧的元素出队。
例如,在Redis中,可以使用列表或有序集合来模拟这种滑动窗口。下面是一个Rdis实现的示例,使用有序集合(sorted set)来实现了滑动时间窗口算法:
public class RateLimiter {
public static boolean isAllowed(String channel) {
long currentTimeMillis = Instant.now().toEpochMilli();
String key = "rate_limiter:" + channel;
try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
// 使用Redis的多个命令来实现滑动窗口
jedis.zremrangeByScore(key, 0, currentTimeMillis - WINDOW_SIZE_IN_SECONDS * 1000);
long requestCount = jedis.zcard(key);
if (requestCount < MAX_REQUESTS) {
jedis.zadd(key, currentTimeMillis, "" + currentTimeMillis);
jedis.expire(key, WINDOW_SIZE_IN_SECONDS);
return true;
} else {
return false;
}
}
}
}
每个请求都以其发生的时间戳作为分数存储在集合中。通过移除旧于当前时间窗口的请求来维护滑动窗口。通过检查集合中的元素数量,以确定是否超过了设定的最大请求数。
应用场景:
注意事项:
<未完待续>