======
滑动窗口算法将一个大的时间窗口分成多个小窗口,每次大窗口向后滑动一个小窗口,并保证大的窗口内流量不会超出最大值,这种实现比固定窗口的流量曲线更加平滑。
滑动窗口
以系统限制用户行为为例子,比如一秒内进行某个操作5次,这种行为应该进行限制,滑动窗口就是记录一个滑动的时间窗口内的操作次数,操作次数超过阈值则进行限流。
public boolean isActionAllowed(String userId, String actionKey, int period, int maxCount) {
// 生成唯一的key
String key = String.format(“hist:%s:%s”, userId, actionKey);
long nowTs = System.currentTimeMillis();
// 使用管道
Pipeline pipe = jedis.pipelined();
pipe.multi();
// 添加当前操作当zset中
pipe.zadd(key, nowTs, “” + nowTs);
// 整理zset,删除时间窗口外的数据 符合条件的保留
pipe.zremrangeByScore(key, 0, nowTs - period * 1000);
// 目前窗口内有多少个操作
Response count = pipe.zcard(key);
// 在生命周期上加一
pipe.