sbc(四)应用限流

作者: crossoverJie | 来源:发表于2017-08-11 10:42 被阅读152次
pexels-photo-306198.jpeg

前言

在一个高并发系统中对流量的把控是非常重要的,当巨大的流量直接请求到我们的服务器上没多久就可能造成接口不可用,不处理的话甚至会造成整个应用不可用。

比如最近就有个这样的需求,我作为客户端要向kafka生产数据,而kafka的消费者则再源源不断的消费数据,并将消费的数据全部请求到web服务器,虽说做了负载(有4台web服务器)但业务数据的量也是巨大的,每秒钟可能有上万条数据产生。如果生产者直接生产数据的话极有可能把web服务器拖垮。

对此就必须要做限流处理,每秒钟生产一定限额的数据到kafka,这样就能极大程度的保证web的正常运转。

其实不管处理何种场景,本质都是降低流量保证应用的高可用。

常见算法

对于限流常见有两种算法:

  • 漏桶算法
  • 令牌桶算法

漏桶算法比较简单,就是将流量放入桶中,漏桶同时也按照一定的速率流出,如果流量过快的话就会溢出(漏桶并不会提高流出速率)。溢出的流量则直接丢弃。

如下图所示:

漏桶算法,来自网络.png

这种做法简单粗暴。

漏桶算法虽说简单,但却不能应对实际场景,比如突然暴增的流量。

这时就需要用到令牌桶算法:

令牌桶会以一个恒定的速率向固定容量大小桶中放入令牌,当有流量来时则取走一个或多个令牌。当桶中没有令牌则将当前请求丢弃或阻塞。

令牌桶算法-来自网络.gif

相比之下令牌桶可以应对一定的突发流量.

RateLimiter实现

对于令牌桶的代码实现,可以直接使用Guava包中的RateLimiter

    @Override
    public BaseResponse<UserResVO> getUserByFeignBatch(@RequestBody UserReqVO userReqVO) {
        //调用远程服务
        OrderNoReqVO vo = new OrderNoReqVO() ;
        vo.setReqNo(userReqVO.getReqNo());

        RateLimiter limiter = RateLimiter.create(2.0) ;
        //批量调用
        for (int i = 0 ;i< 10 ; i++){
            double acquire = limiter.acquire();
            logger.debug("获取令牌成功!,消耗=" + acquire);
            BaseResponse<OrderNoResVO> orderNo = orderServiceClient.getOrderNo(vo);
            logger.debug("远程返回:"+JSON.toJSONString(orderNo));
        }

        UserRes userRes = new UserRes() ;
        userRes.setUserId(123);
        userRes.setUserName("张三");

        userRes.setReqNo(userReqVO.getReqNo());
        userRes.setCode(StatusEnum.SUCCESS.getCode());
        userRes.setMessage("成功");

        return userRes ;
    }

详见此

调用结果如下:

1.jpg

代码可以看出以每秒向桶中放入两个令牌,请求一次消耗一个令牌。所以每秒钟只能发送两个请求。按照图中的时间来看也确实如此(返回值是获取此令牌所消耗的时间,差不多也是每500ms一个)。

使用RateLimiter有几个值得注意的地方:

允许先消费,后付款,意思就是它可以来一个请求的时候一次性取走几个或者是剩下所有的令牌甚至多取,但是后面的请求就得为上一次请求买单,它需要等待桶中的令牌补齐之后才能继续获取令牌。

总结

针对于单个应用的限流RateLimiter够用了,如果是分布式环境可以借助redis来完成。具体实现在接下来讨论。

项目:https://github.com/crossoverJie/springboot-cloud

博客:http://crossoverjie.top

weixinchat.jpg

相关文章

  • sbc(四)应用限流

    前言 在一个高并发系统中对流量的把控是非常重要的,当巨大的流量直接请求到我们的服务器上没多久就可能造成接口不可用,...

  • 高并发环境下的限流策略

    本文将从以下几个方面分析限流策略: 什么是限流限流算法限流算法的应用 什么是限流 在开发高并发系统时,有很多手段来...

  • 聊聊高并发系统之限流特技-2

    摘要:上一篇《聊聊高并发系统限流特技-1》讲了限流算法、应用级限流、分布式限流;本篇将介绍接入层限流实现。 接入层...

  • 聊聊高并发系统限流特技-2

    转载来自开涛的聊聊高并发系统限流特技-2 上一篇《聊聊高并发系统限流特技-1》讲了限流算法、应用级限流、分布式限流...

  • 分布式限流

    前言 本文接着上文应用限流进行讨论。 之前谈到的限流方案只能针对于单个 JVM 有效,也就是单机应用。而对于现在普...

  • 分布式限流的方案

    前言 本文接着上文应用限流进行讨论。 之前谈到的限流方案只能针对于单个 JVM 有效,也就是单机应用。而对于现在普...

  • Java应用限流

    在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流:缓存:缓存的目的是提升系统访问速度和增大系统处理容量...

  • 应用级限流

    上一篇 <<<自定义封装限流算法[https://www.jianshu.com/p/e277e4cfe8aa]下...

  • 限流框架系列之常见限流算法

    四种常见的限流算法 固定时间窗口限流算法 滑动时间窗口限流算法 令牌桶限流算法 漏桶限流算法 算法比较 算法确定参...

  • 技术博客

    1. 基于Redis实现分布式应用限流

网友评论

    本文标题:sbc(四)应用限流

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