In high concurrency scenarios, often inseparable from limiting, there are limiting based service, such as full-flow limitations, common limiting algorithm tainted token bucket algorithm and pass algorithm (before there is an article explaining)
The use google Guava framework limiting, using the token bucket algorithm is a java library expansion. There are classes for a RateLimiter
RateLimiterFilter inheritance ZuulFilter, pre-filter
package com.chwl.cn.filter;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpStatus;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
/**
* 限流 --在token验证完之后进行
* @author Administrator
*
*/
public class RateLimiterFilter extends ZuulFilter{
private static final Double RATE_LIMITER_NUM=1.0;
private final RateLimiter rateLimiter = RateLimiter.create(RATE_LIMITER_NUM);
@Override
public boolean shouldFilter() {
//如果在此过滤器之前已经有过滤器验证不通过且不需要再执行其他过滤器情况下,判断是否执行此过滤器
RequestContext ctx = RequestContext.getCurrentContext();
if(!ctx.sendZuulResponse()){
return false;
}
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletResponse response = currentContext.getResponse();
response.setContentType("application/json; charset=utf-8");
if(!rateLimiter.tryAcquire()){
currentContext.setSendZuulResponse(false);
response.setStatus(HttpStatus.SC_UNAUTHORIZED);//401
try {
response.getWriter().append("网络繁忙,请稍后再试");
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return -3;
}
}
package com.chwl.cn.filter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Filter {
/**
* token校验处理 order -4
* @return
*/
@Bean
public TokenAuthFilter tokenAuthFilter(){
return new TokenAuthFilter();
}
/**
* 限流处理 order -3
* @return
*/
@Bean
public RateLimiterFilter rateLimiterFilter(){
return new RateLimiterFilter();
}
}
It is simple to use, but the current limit is not tricky.
Meticulous service to each micro then determines the next service point is to add a simple unified name on it
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletResponse response = currentContext.getResponse();
response.setContentType("application/json; charset=utf-8");
String requestURI = currentContext.getRequest().getRequestURI();
if (requestURI.contains("/apigateway/order")) {//统一的订单服务接口,订单相关的接口都在此应用
if (!rateLimiter.tryAcquire()) {
currentContext.setSendZuulResponse(false);
response.setStatus(HttpStatus.SC_UNAUTHORIZED);// 401
try {
response.getWriter().append("网络繁忙,请稍后再试");
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
server:
port: 7001
#服务的名称
spring:
application:
name: chwl-api-gateway-zuul-7001
# main:
# allow-bean-definition-overriding: true
redis:
# database: 1
host: 127.0.0.1
port: 6379
password:
timeout: 10000
lettuce:
pool:
minIdle: 0
maxIdle: 10
maxWait: 10000
max-active: 10
sentinel:
master: master-6379
nodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#defaultZone: http://localhost:2001/eureka #这个地址就是EurekaServer注册中心的地址
defaultZone: http://ypp:[email protected]:2001/eureka/,http://ypp:[email protected]:2002/eureka/
instance:
instance-id: chwl-api-gateway-zuul-7001
prefer-ip-address: true #访问路径可以显示IP地址
#自定义路由映射
zuul:
routes:
chwl-provider-product: /apigateway/product/**
chwl-provider-order: /apigateway/order/**
chwl-provider-member: /apigateway/member/**
#统一入口为上面的配置,其他入口忽略
ignored-patterns: /*-provider-*/**
#忽略整个服务,对外提供接口
#ignored-services: chwl-provider-product