一. 限流介紹
-
爲什麼使用限流?根據木桶效應,限流保證下游服務可用
-
限流方式
-
網關層限流
-
nginx層限流
-
二. 谷歌guava框架的使用(網關層限流)
-
創建自定義過濾器,繼承ZuulFilter
-
創建令牌桶,設置爲static final(根據壓測設置qps數)
-
在filterOrder中設置優先級
-
在run中,通過RATE_LIMITER.tryAcquire()以非阻塞方式獲取令牌
整體代碼示例:
@Component
public class OrderRateLimiterFilter extends ZuulFilter {
//每秒產生1000個令牌
private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return -4;
}
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//只對訂單接口限流
if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())){
return true;
}
return false;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
//阻塞方式獲取令牌,方法中如果添加int類型參數,就是設置阻塞時間
//if(!RATE_LIMITER.acquire()){}
//非阻塞方式獲取令牌,方法中如果添加int類型參數,就是設置阻塞時間(一般限流不加zusaishijian)
if(!RATE_LIMITER.tryAcquire()){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
另:網關集羣搭建
-
Nginx需要通過lvs+keepalive做高可用,通過僞ip映射,實現nginx集羣
-
網關集羣搭建的時候,令牌數,應該爲“qps數/網關節點數”