Google的Guava工具包中就提供了一个限流工具类——RateLimiter,本文也是通过使用该工具类来实现限流功能。RateLimiter是基于“令牌通算法”来实现限流的。
令牌桶: 1.令牌生成器以固定速率向令牌桶放令牌,如果桶满了就丢弃 2.调用者去令牌桶拿令牌,拿不到就拒接访问。
限流的本质有两点: 1.生成令牌 2.抢令牌
step1: pom.xml
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
step2. 代码,在网关中增加限流过滤器,每秒最多支持100并发,超过后拒绝请求
@Component
public class LimitFilter extends ZuulFilter {
//以固定的速度每秒产生10个令牌,
private static final RateLimiter RATE_LIMITER = RateLimiter.create(10);
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return -100;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
System.out.println("过滤器--1");
RequestContext currentContext = RequestContext.getCurrentContext();
if (RATE_LIMITER.tryAcquire()) {
return null;
} else {
currentContext.set("limit", false);//控制过滤器--2
currentContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}