import com.google.common.util.concurrent.RateLimiter;
引用guava封装的RateLimiter
private Map<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();
//tps从数据库或者缓存中获取
RateLimiter limiter = rateLimiterMap.get(_key);
if (limiter == null) {
limiter = RateLimiter.create(tps);
rateLimiterMap.put(_key, limiter);
}
checkRate(limiter, tps);
将每个key对应的RateLimiter存到ConcurrentHashMap中
private void checkRate(RateLimiter limiter, double expectedRate) throws BusinessException {
// 检查流量控制是否更改了。
if(Math.abs(expectedRate - limiter.getRate()) > 1){
limiter.setRate(expectedRate);
}
if(limiter.tryAcquire(configBean.getMaxTpsLimitTimeout(), TimeUnit.MILLISECONDS) == false){
// 丢弃
throw new Exception("触发TPS限流控制,主动丢包");
}
}
_key可以是用户标识也可以是系统单节点标识,双重限流。
用户较少时可以用次方法,单如果用户较多,可以考虑使用缓存中的key-value