背景
某服务调用,因服务器性能问题,无法直接使用最大qps进行调用,需要动态加速
逻辑
设置最大加速时间,设置允许加速到的最大qps
代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.atomic.AtomicLong;
public class WarmUpManager {
private static final Logger logger = LoggerFactory.getLogger(WarmUpManager.class);
private final Long second;
private final Long maxQps;
private String description;
private final AtomicLong secondQps;
private AtomicLong requestCount = new AtomicLong(0);
private long currentTimeMillis = System.currentTimeMillis();
private final long interval = 1000;
private final long initTime = System.currentTimeMillis();
private final long warmUpLimitStepValue;
private final long endTimeMillis;
public WarmUpManager(long second, long maxQps, String description) {
if(maxQps <= 0){
throw new IllegalArgumentException("maxQPs 必须大于0");
}
this.second = second;
this.maxQps = maxQps;
secondQps = new AtomicLong(maxQps / second);
if (secondQps.get() == 0) {
secondQps.set(1);
}
warmUpLimitStepValue = secondQps.get();
if(description == null){
this.description = "";
}
endTimeMillis = currentTimeMillis + second * interval;
}
public void warmUp() throws InterruptedException {
long now = System.currentTimeMillis();
if (now >= endTimeMillis ) {
return;
}
long total = currentTimeMillis + interval;
if ((now < total) && requestCount.incrementAndGet() > secondQps.get()) {
LogUtils.info(logger, "{} 预热中,已预热{}秒,qps限流:{}", description, ((now - initTime) / 1000) + 1, secondQps.get() + 1);
Thread.sleep(total - now);
currentTimeMillis = System.currentTimeMillis();
requestCount = new AtomicLong(0);
if (secondQps.get() + warmUpLimitStepValue < maxQps) {
secondQps.getAndAdd(warmUpLimitStepValue);
}
}
}
}
使用方式
public class Test {
public static void main(String[] args) throws InterruptedException {
WarmUpManager warmUpManager = new WarmUpManager(10L,5L,"");
int max = 1000;
for (int i = 0; i < max; i++) {
warmUpManager.warmUp();
System.out.println("==========> " + ( i));
}
System.out.println("====run done ");
}
}
|