Java限流之令牌桶算法、漏桶算法

限流在实际使用场景中应用十分广泛,尤其针对并发场景下的高并发,为了保证系统的可用性,我们需要采取一些限流措施降级,以防止非预期的请求对系统压力过大而引起的系统瘫痪。

对于过量的请求一般的措施就是丢掉多余的请求,或者让请求排队,再或者引流

下面说下常用的限流方式:

1.计数器方法

比如在1分钟内限制请求次数不超过100,那我们定义一个变量counter,每来一个请求则counter加1,如果在一分钟之内counter累计超过100,新来的请求则超过限制。然后,超过1s之后,这个counter就重置。这是比较简单的计数器法;

但是这种方法会有一个问题,那就是比如某个人在0:59秒的时候打了100个请求过来,然后,在1min的时候counter就置零了,他又在1:01的时候打了100个请求过来,所以说,在最近的1min之内其实是接收到200个请求,这明显超出了我们的预期,所以说这种方法不满足我们的需求。

聪明的小伙伴一眼就能看出问题所在,其实是我们统计的精度太低了,于是就引出下面的滑动窗口计数法;

2.滑动窗口

比如我们把1min划分成6个小格,则每10s为一个分割单位,比如在0:35分钟来了100个请求,则会落在0:30-0:39这个区间内,当1:01再来100个请求时,显然,最近1分钟内的请求次数超过了100,那么这100个请求则被限制住了,这种是符合我们的预期。但是滑动窗口对存储有比较大的需求,尤其在窗口比较小的情况下不满足需求。

3.漏桶算法

漏桶算法的思路就是,水(请求)先进入漏桶里,漏桶以一定的速度出水(接口响应时间),当水流入速度(接口请求的速度)越来越大时,漏桶就会溢出,然后新来的请求就会被拒绝。无论请求量多大,漏洞的出水速率是不变的,所以针对突发的大流量场景,这种方案是不支持的。

漏洞算法示意图

4.令牌桶算法

令牌桶算法是我们日常使用比较多的方案,它的基本方案是:系统以恒定速率向桶里放入令牌,,如果桶满了则不加。当请求来的时候,从桶里拿走一个令牌,如果桶里没有令牌则阻塞或者拒绝新的请求。令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 

可以参考RateLimiter类来进行实际应用。


令牌桶算法示意图
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 夜莺2517阅读 127,816评论 1 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 12,748评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 7,526评论 2 9
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 11,356评论 4 8

友情链接更多精彩内容