依赖redis做并发访问限流控制
//限流redisKey前缀
private String REDIS_RATE_LIMIT_PREX = "gw:rl:";
//初始化方法,系统启动时调用
public void init(){
//删除所有限流Key
jedisClient.keys(REDIS_RATE_LIMIT_PREX+"*").forEach(key -> jedisClient .delete(key));
//从数据库中取出所有限流配置
Map rateLimitMap = rateLimitDao.getAllRateLimit();
//将限流配置加载进redis
rateLimitMap.foreach((key,value) -> {if(value >= 0){
jedisClient.set(REDIS_RATE_LIMIT_PREX+key,value);
}});
}
//判断请求是否超出限制
public void tryAcquire(String key) throws RateLimitException{
//原子操作减一
if(jedisClient.increment(REDIS_RATE_LIMIT_PREX+key,-1) < 0){
throw new RateLimitException("接口" + key + "处理中请求超过最大限制");
}
}
//请求处理完之后回调
public void callBack(String key){
//原子操作加一
jedisClient.increment(REDIS_RATE_LIMIT_PREX+key,1);
}
/**
* 动态设置限流请求数
*
* @param key 限流key
* @param limit 限流数量
*/
public void setRate(String key,int limit){
//查出原来限流数量
RateLimit ratelimit = rateLimitDao.getByKey(key);
//计算出增量限流数
int incrementLimit = limit - rateLimit.getLimit();
//执行redis原子增量操作
jedisClient.increment(REDIS_RATE_LIMIT_PREX+key,incrementLimit);
//修改数据库到新的限流数量
rateLimit.setLimit(limit);
rateLimitDao.update(rateLimit);
}
网友评论