限流算法之计数器(一)

一、为什么需要限流

按照服务的调用方,可以分为以下几种类型服务

1、与用户打交道的服务

比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮:

  • 用户增长过快(这是好事)
  • 因为某个热点事件(微博热搜)
  • 竞争对象爬虫
  • 恶意的请求

这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量打进来,如果真碰上这种情况,扩容是根本来不及的(弹性扩容都是虚谈,一秒钟你给我扩一下试试)

2、对内的RPC服务

在这里插入图片描述
从上图可以看出上游的A、B服务直接依赖了下游的基础服务C、D和E,对于A,B服务都依赖的基础服务D这种场景,服务A和B其实处于某种竞争关系,如果服务A的并发阈值设置过大,当流量高峰期来临,有可能直接拖垮基础服务D并影响服务B,即雪崩效应来了

二、限流算法实现

常见的限流算法有:计数器、漏桶(Leaky Bucket) 、令牌桶(Token Bucket)。

1、计数器

采用计数器实现限流有点简单粗暴,一般我们会限制一段时间能够通过的请求数,比如限流qps为100/min

1)、访问量限流(通过限制单位时间段内调用量来限流)

原理:

确定方法的最大访问量MAX,每次进入方法前计数器+1,将结果和最大并发量MAX比较,如果大于等于MAX,则直接返回;如果小于MAX,则继续执行。

示例:
测试代码路径:https://github.com/1309893329/study/tree/master/dailystudy/src/main/java/lm/study/daily/run/limit
在这里插入图片描述

优缺点:
对于访问量限流这种限流方式,实现简单,适用于大多数场景,阈值可以通过服务端来动态配置,甚至可以当做业务开关来使用,
但也有一定的局限性,因为我们的阈值是通过分析单位时间段内调用量来设置的,如果它在单位时间段的前几秒就被流量突刺消耗完了,将导致该时间段内剩余的时间内该服务“拒绝服务”,可以将这种现象称为“突刺现象”。

2)、并发量限流(通过限制系统的并发调用程度来限流)

原理:

确定方法的最大并发量MAX,每次进入方法前计数器+1,将结果和最大并发量MAX比较,如果大于等于MAX,则直接返回;如果小于MAX,则继续执行;退出方法后计数器-1。
比如限制服务的并发访问数是100,而服务处理的平均耗时是10毫秒,那么1分钟内,该服务平均能提供( 1000 / 10 ) * 60 * 100 = 6000 次

示例:
测试代码路径:https://github.com/1309893329/study/tree/master/dailystudy/src/main/java/lm/study/daily/run/limit/aop
在这里插入图片描述

优缺点:
并发量限流一般用于对于服务资源有严格限制的场景,但是某个服务在业务高峰期和低峰期的并发量很难评估,这给并发阈值的设置带来了困难,但我们可以通过线上业务的监控数据来逐步对并发阈值进行调优,只要肯花时间,我们总能找到一个即能保证一定服务质量又能保证一定服务吞吐量的合理并发阈值,从表面上看并发量限流似乎很有用,但也不可否认,它仍然可以造成流量尖刺,即每台服务器上该服务的并发量从0上升到阈值是没有任何“阻力”的,这是因为并发量考虑的只是服务能力边界的问题。

2、漏桶(Leaky Bucket)

在这里插入图片描述
为了消除"突刺现象",可以采用漏桶算法实现限流,漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,
当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变。
不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,
可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃

3、令牌桶(Token Bucket)

在这里插入图片描述
从某种意义上讲,令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。
在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。
每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。
放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,
这时进来的请求就可以直接拿到令牌执行,比如设置qps为100/s,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,
这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行

参考资料

https://www.jianshu.com/p/76cc8ba5ca91

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值