本文主要给大家展示“java如何实现单机界面的限流”。内容简单易懂,条理清晰。希望能帮你解开疑惑。让边肖带领大家学习学习《java如何实现单机界面的电流极限》一文。
简单来说,就是设置一个接口,在一定时间内只接受固定次数的请求。例如,/add接口一秒钟最多可以接收100个请求,其中许多请求会直接拒绝。这个问题很常见,场景也很好理解。直接编码:
/**
*单机限流
*/
@Slf4j
publicclassFlowLimit{
//接口限流上限和限流时间缓存
privatestaticCacheString,atomiconglocalccache=cachebuilder . new builder()。最大大小(100)。expireAfterWrite(1000,时间单位。毫秒)。build();
//每个接口的上限缓存
privatestaticMapString,longmaxflow limitmap=new concurrenthashmap();
privatedstatifnlowlimitinstance=new flow limit();
//这个块的目的是初始化每个接口的上限,以下变量:apiFlowLimitConfigure
//在实际使用中,我们应该从db或其他地方获取每个接口的设置电流限制上限值,
//这样就可以动态调整接口上限,比如直接修改db,就可以调整接口限流,无需发布。
静态{
newscheduledreadpoolexecutor(1,可运行-{ 0
Threadthread=newThread(可运行,' API-FlowLimit-configure ');
//thread . setdaemon(true);
returnthread
}).scheduleAtFixedRate(()-{ 0
尝试{
stringiflowlimitconfigure=' { \ ' DOADD ' :100 } ';//表示/doAdd接口一秒钟接受100个请求。
MapmapObj=jsonobject . parseobject(apiflolimitconfigure,map . class);
if(mapObj!=null){ 0
mapObj.forEach((key, value) -> {
if(value != null){
instance.setMaxFlowLimit(key.toString(), new Long(value.toString()));
}else{
log.warn(key + " - 设置接口限流发现限流值为空,设置默认值");
instance.setMaxFlowLimit(key.toString(), 100L);
}
});
}
} catch (Exception e) {
log.error("设置接口限流出现异常{}", e);
}
}, 0, 3, TimeUnit.SECONDS);
}
public static FlowLimit getInstance() {
return instance;
}
private FlowLimit setMaxFlowLimit(String key, Long maxFlowLimit) {
maxFlowLimitMap.put(key, maxFlowLimit);
return this;
}
public Boolean isAvailable(String key) {
return checkAvailable(key, 1L);
}
public Boolean isAvailable(String key, Long incrNum) {
return checkAvailable(key, incrNum);
}
private Boolean checkAvailable(String key, Long incrNum){
Long maxFlowLimit = maxFlowLimitMap.get(key);
if (null == maxFlowLimit || maxFlowLimit == 0) {
return true;
}
if (incrAndGet(key, incrNum) <= maxFlowLimit.longValue()) {
return true;
} else {
return false;
}
}
private long incrAndGet(String key, final long n) {
try {
return localCache.get(key, new Callable<AtomicLong>() {
@Override
public AtomicLong call() throws Exception {
return new AtomicLong(0);
}
}).addAndGet(n);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return 0;
}
public long get(String key) {
return incrAndGet(key, 0);
}
}
上面这个就是单机限流逻辑,代码不难,感觉没必要使用ConcurrentHashMap,不过感觉无所谓了
这段代码只需要加在需要限流的接口前面:
@GetMapping("doAdd") public Boolean doAdd(){ FlowLimit instance = FlowLimit.getInstance(); //单例获取 //查看当前的/doAdd接口是否触发了限流 Boolean flowLimitFlag = instance.isAvailable("doAdd"); if(!flowLimitFlag){ log.warn("触发限流,拒绝请求"); return false; } //doAdd() return true; }
调用实例如上
上面这个限流其实是有一定问题的:比如你限定10秒钟1000次,在第9.9秒的时候,突然进来1000个请求,然后第10.1秒的时候,攻击者,又进来1000次请求,这样,0.2秒之内,进来2000次请求。。。
所以这个时候就需要令牌桶或者其他算法了,其他算法后面再写
以上是“java如何实现单机接口限流”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/116537.html