微服务之接口限流技术guava框架

为啥要接口限流?

为了防止QPS过高而导致服务宕机。

1、QPS是什么?

接口流量峰值,同一时间访问的最大人数 (读写) 一般大概约为1000+ 也就是1000QPS。单读的话可以达到3000+。当然写的强度和你的业务复杂度有关,一般业务不复杂,1000+没啥问题,机器是可以顶的住的。

2、结合cloud zuul网关设计限流方案

首先来了解下 zuul 网关的生命周期
在这里插入图片描述
每个阶段出现错误的执行情况

当 pre 出现异常 ——>error ——>post——>HTTP
当 routing 出现异常——>error——>post——>HTTP
当 error 出现异常——>post——>HTTP
当 post 出现异常——>error——>HTTP

zuulfilter的使用

/**
 * @author wyy
 * @date 19/5/23
 * zuul filter过滤器
 */
 @Component
public class LoginFilter extends ZuulFilter {
    /**
     * filter类型 前置filter 和后置filter
     * 是以constant定义的
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 过滤器顺序  越小越先执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 过滤器是否生效  true 生效  false  不生效
     * @return
     */
    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        System.out.println(request.getRequestURI());

        //ACL   拦截下面的接口 忽略大小写   拼写接口需要和网关自定义接口一致
        if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())){
            return true;
        }else if ("/apigateway/order/api/v1/order/list".equalsIgnoreCase(request.getRequestURI())){
            return true;
        }else if ("/apigateway/order/api/v1/order/find".equalsIgnoreCase(request.getRequestURI())){
            return true;
        }
        return false;
    }

    /**
     * 业务处理逻辑   和thread run()方法有点像
     * @return
     * @throws ZuulException
     */
  @Override
public Object run() throws ZuulException {
    //如果上面的拦截生效 并true 就会跳到这里进行业务逻辑处理
    RequestContext requestContext = RequestContext.getCurrentContext();
    HttpServletRequest request = requestContext.getRequest();
    String token = request.getHeader("token");
    if(StringUtils.isBlank(token)){
        token = request .getParameter("token");
    }
    //登录校验逻辑  根据公司情况自定义 JWT

    if(StringUtils.isBlank(token)){
          requestContext.setSendZuulResponse(false);
          requestContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
    }
    return null;
}
}

接口限流 guava框架 限流原理
在这里插入图片描述

实现代码

/**
 * 使用guava限流框架
 * @author wyy
 * @date
 */
public class OrderRateLimitFilter 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();
        /* System.out.println(request.getRequestURI());*/
        //需要对那个接口限流就把哪个接口写下去
        //ACL   拦截下面的接口 忽略大小写
        if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        }
        return false;
    }

    @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;
    }
}
发布了47 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42083036/article/details/105113826