关于计数器的核心实现参考自如下:
https://github.com/halilduygulu/redis-sliding-window-counter
课题需求是需要对可能产生高并发的接口进行计数管理,如10秒内最大允许访问100次,超出次数拒绝。
基本上有3种实现方式
-
指定时限,如每天0点开始,每10秒开放一定次数。计时窗口固定,过期清空
-
采用时间滑动窗口,每秒(毫秒)计时窗口滑动,重新启动计数
-
采用令牌方式,每秒产生10枚令牌,只有拿到令牌的允许访问,否则排队
这里是实现的第二种方式,为了支持分布式,采用了redis,同时利用redis的特性zset可以简洁高效的实现滑动窗口。
完整代码如下:
package slidingWindowCounter;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
/**
* 根据时间滑动窗口计数
*/
public class SlidingWindowCounter {
private static SlidingWindowCounter instance = null;
private JedisPool jedisPool = null;
/*
* 单