javaweb
javaweb copied to clipboard
限流算法
1.总量限流
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "requestFilter")
public class LimitFilter implements Filter {
private static final int MAX_COUNT = 20000;
private final static AtomicInteger filterCount = new AtomicInteger(0);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("before {}",filterCount);
if (filterCount.get() > MAX_COUNT) {
//请求个数太多,跳转到排队页面
servletRequest.getRequestDispatcher("index.html").forward(servletRequest, servletResponse);
} else {
//请求个数加1
filterCount.incrementAndGet();
filterChain.doFilter(servletRequest, servletResponse);
//访问结束,请求个数减1
filterCount.decrementAndGet();
}
}
@Override
public void destroy() {
}
}
使用guava cache控制某个时间窗请求
@Slf4j
public class GuavaLimiter {
private static LoadingCache<Long,AtomicLong> counter;
private static final long limit = 1000;
public static void main(String[] args) throws ExecutionException {
counter = CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader<Long, AtomicLong>() {
@Override
public AtomicLong load(Long key) throws Exception {
return new AtomicLong(0);
}
});
work();
}
private static void work() throws ExecutionException {
while (true){
long current = System.currentTimeMillis() / 1000;
if(counter.get(current).incrementAndGet()>limit){
log.info("限流"+current);
continue;
}
//TODO
log.error("业务处理中");
}
}
}
基于guava limiter的平滑限流
Long start = System.currentTimeMillis();
RateLimiter limiter = RateLimiter.create(10.0); // 每秒不超过10个任务被提交
for (int i = 0; i < 100; i++) {
limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞
System.out.println("call execute.." + i);
}
Long end = System.currentTimeMillis();
System.out.println(end - start);