美文网首页
SpringCloud-Zuul-03限流应用

SpringCloud-Zuul-03限流应用

作者: 小亮__ | 来源:发表于2019-06-24 07:33 被阅读0次

    在高并发应用场景中,经常会出现访问突然增大的情况,例如:
    某天A君突然发现自己的接口请求量突然涨到之前的10倍,没多久该接口几乎不可使用,并引发连锁反应导致整个系统崩溃。如何应对这种情况呢?生活给了我们答案:比如老式电闸都安装了保险丝,一旦有人使用超大功率的设备,保险丝就会烧断以保护各个电器不被强电流给烧坏。同理我们的接口也需要安装上“保险丝”,以防止非预期的请求对系统压力过大而引起的系统瘫痪,当流量过大时,可以采取拒绝或者引流等机制。

    常见的限流算法,有以下两种

    漏桶算法

    漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率

    令牌桶算法

    对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如图2所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

    SpringCloud微服务中,我们可以使用Zuul来实现对于接口的限流,我们只需要编写一个过滤器就可以,例如以下例子:
    我们可以编写一个pre类型的Zuul过滤器,然后使用Google Guava 为我们提供了限流工具类RateLimiter ,来完成限流的功能(该类基于令牌桶算法来完成限流,非常易于使用)

    单节点限流案例:

    @Component
    public class RateLimitZuulFilter extends ZuulFilter {
        private final RateLimiter rateLimiter = RateLimiter.create(1000.0);
        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE;
        }
        @Override
        public int filterOrder() {
            return Ordered.HIGHEST_PRECEDENCE;
        }
        @Override
        public boolean shouldFilter() {
            // 这里可以考虑弄个限流开启的开关,开启限流返回true,关闭限流返回false
            return true;
        }
        @Override
        public Object run() {
            try {
                RequestContext currentContext = RequestContext.getCurrentContext();
                HttpServletResponse response = currentContext.getResponse();
                //判断如果获取令牌失败,则抛出异常
                if (!rateLimiter.tryAcquire()) {
                    HttpStatus httpStatus = HttpStatus.TOO_MANY_REQUESTS;
                    response.setContentType(MediaType.TEXT_PLAIN_VALUE);
                    response.setStatus(httpStatus.value());
                    response.getWriter().append(httpStatus.getReasonPhrase());
    
                    currentContext.setSendZuulResponse(false);
    
                    throw new ZuulException(
                            httpStatus.getReasonPhrase(),
                            httpStatus.value(),
                            httpStatus.getReasonPhrase()
                    );
                }
            } catch (Exception e) {
                ReflectionUtils.rethrowRuntimeException(e);
            }
            return null;
        }
    }
    

    分布式场景限流案例:

    相关文章

      网友评论

          本文标题:SpringCloud-Zuul-03限流应用

          本文链接:https://www.haomeiwen.com/subject/vjvzfctx.html