ZUUl网关-----过滤器实现登陆鉴权,高并发接口限流
(1)过滤器实现登陆鉴权
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 登录过滤器
*/
@Component
public class LoginFilter extends ZuulFilter {
/**
* 过滤器类型,前置过滤器 后置 访问时 等 登陆肯定是请求接口前进行判断 ,此处为前置
* @return
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 过滤器顺序,越小越先执行
* @return
*/
@Override
public int filterOrder() {
return 4;
}
/**
* 过滤器是否生效 true 过滤器生效 执行下方run()
* @return
*/
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//
if ("需要登录的路径".equalsIgnoreCase(request.getRequestURI())){
return true;
}
return false;
}
/**
* 业务逻辑
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
//获取上下文对象
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//模拟获取token 进行判断
String token = request.getHeader("token");
if(StringUtils.isBlank((token))){
token = request.getParameter("token");
}
//登录校验逻辑 根据业务场景自定义
if (StringUtils.isBlank(token)) {
requestContext.setSendZuulResponse(false);
//返回响应码 401
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
步骤总结:
1.自定义一个类 实现ZuulFilter
2.覆写其中 四个方法 四个方法的作用,代码中已做说明
(2)高并发下接口限流
在高并发下 进行限流 限制QPS(并发数)当并发数大于定义人数时 限流外的人员将无法访问该接口 降低系统压力
example: 订单接口
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 订单限流
*/
@Component
public class OrderRateLimiterFilter extends ZuulFilter {
//每秒产生2000个令牌 即设定每秒最好QPS为2000人
private static final RateLimiter RATE_LIMITER = RateLimiter.create(2000);
/**
* 过滤器类型,前置过滤器 后置 访问时 等 登陆肯定是请求接口前进行判断 ,此处为前置
* @return
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 过滤器顺序,越小越先执行
* @return 查看得知 系统设定最小为-3,我此处设为-4意思为 所有过滤器 他最先执行
*/
@Override
public int filterOrder() {
return -4;
}
/**
* 过滤器是否生效 true 过滤器生效 执行下方run()
* @return
*/
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//只对订单接口限流 次数Url为自定义订单路径
if ("/zuuiapi/order/pay".equalsIgnoreCase(request.getRequestURI())) {
return true;
}
return false;
}
/**
* 业务逻辑
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
//尝试获取令牌 每一个用户访问该接口都会占用一个令牌 如果获取不到令牌说明已达到限流峰值 则返回数据抛出响应码
if (!RATE_LIMITER.tryAcquire()) {
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
此仅仅为订单接口 限流 如果要限流多个 重复操作即可,,