Sentinel实现限流

1. 相关介绍        

        在了解Sentinel的限流算法之前,我们先简单了解一下Sentinel。

        Sentinel的官网是这样介绍Sentinel的:随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

        下面进行介绍。

2. Sentinel实现限流

        Sentinel的限流算法常见的有三种实现:(1)滑动时间窗口(2)令牌桶算法(3)漏桶算法

下面对上面的三种限流算法进行一一介绍。

2.1 滑动时间窗口算法

2.1.1 介绍

        说到滑动时间窗口算法之前,就得先说说固定窗口计数算法。什么是固定窗口计数算法呢?固定窗口计数算法:将时间分成一个个单位,对每个切割出来的时间段里面进行计数,来了一个请求,计数器counter加1,达到阈值之后就拒绝请求,直到下一个时间段计数器重置为0。

        滑动窗口算法是固定窗口计数算法的优化。那什么是滑动时间窗口算法呢?就是将时间以每一秒进行划分的前提,再次划分为n个更小的区间从而形成多个窗口。这里引入几个参数,一个是Interval,表示一个时间段,窗口的时间跨度,简单来说就是一个时间间隔。另外一个就是参数currentTime,表示当前的时间。这里举个例子,比如说我们现在设置一个时间间隔为1s,我们设计为5个区间,这样子我们每个小区间都是200ms,我们只要统计的就是在每个200ms内的请求。

        一旦我们给定了上面的几个参数之后,我们就可以给定一个限定的阈值,我们只允许在这个时间的区间范围内,请求的次数不能多于我们限定的阈值。但有请求进来的时候,我们就可以进行判断,如果当前时间减掉窗口时间跨度后的第一个窗口到我们的currentTime所在的时间内,也就是窗口范围为{[currentTime-Interval],currentTime},在这个范围内,如果请求的数量少于我们阈值的话,那么请求就直接放放行,反之如果超过了,后续的那些请求都会被丢弃。

2.1.2 图示

     

         这里以每秒做作为一个窗口跨度,区间划分为两个小区间,最多请求设置为3,也就是阈值设置为3。

        首先,从0开始,第一个区间为[0,1000ms]中,我们可以看到,第一个小区间[0,500ms)中,200ms的时候来了一个请求,400ms的时候来了一个请求,所以说第一个小区间的counter=2,小于我们设置的阈值。接下来在[500ms,1000ms)的区间内,在900ms的时候来了一个请求,此时[500ms,1000ms)这个区间内只有1个请求,加上我们前面[0,500ms)的请求数,一共有3个,并没有超过阈值,此时请求全都被接收并进行处理,窗口滑动,从[0,1000ms)滑动到[500ms,1500ms)这个区间。

        同理,[1000ms,1500ms)这个区间,在1250ms来了一个请求,此时counter为2(900ms一个请求+1250ms一个请求),接收这个请求。到了1300ms的时候又进来一个请求,此时的counter为3(前面两个请求+1300ms一个请求),同样不超过阈值,同样接收并处理这个请求。然后在1400ms的时候,又进来了一个请求,此时的counter为4个(前面三个请求+1400ms一个请求),已经超过了我们设置的阈值的,此时我们就会丢弃这个请求。大致的执行过程就是这样子。

2.1.3 运用

        默认限流模式是基于滑动窗口算法。

2.1.4 总结

       通过上面的举例,我们不难发现,前面提到的固定窗口算法其实就是滑动窗口算法的一个特例,就是我们将窗口数划分为1个的情况。

        优点:对于滑动窗口算法,通过使用分区间的方式,使我们能够对流量的控制变得更加平滑,并且对于流量的控制精确度会随着我们窗口的区间越小而变高。

        缺点:不能应对徒增流量。也就是说,一旦我们在某个时间范围内,突发高峰,很多请求同时打了进来,而我们却只能处理最大阈值数量的请求,其他的请求都会被拒绝掉。

        PS:除了这个缺点外,其实还有一个小问题。在我们将窗口划分得比较少的时候,假设只有2个区间,阈值为3,在497ms,498ms,499ms时候,有三个请求,这个时候这三个请求都是会处理的。此时在[500,1000ms)一个请求都没有(有请求也会被拒绝),在1001ms,1002ms,1003ms的时候来了三个请求,这个时候我们的窗口是在[500ms,1500ms)的,所以这三个请求都会被接收并处理。然而我们可以看到,在[497,1497ms]这个窗口内,此时处理的请求已经达到了6个,远超了我们阈值,但是这6个请求都会处理了,这个就是一个小小的问题,出现的原因就是窗口划分得少,可能会导致上面那样的情况发生。(为什么说是一个小小的问题呢,就是因为实际中这种问题出现得比较少,其实我们将窗口500ms就可以将流量控制好了,并且我们设置阈值的时候,也并不会完全将服务器能处理的阈值作为我们的阈值,一般都是会往下调一点,所以不用担心流量超过阈值会导致服务器处理不来的问题)

2.2 令牌桶算法

2.2.1 介绍

        令牌桶算法就是有一个抽象的桶,这个桶呢其实就是一个容器,用来存储我们的令牌。在这个容器内,桶会以每秒固定的速度来生成令牌,并将令牌存入到桶中,当令牌桶满了以后,生成的多余的令牌就会被丢弃。每次我们的请求进来的时候,它就会对应地尝试从桶中获取一个令牌,只有拿到令牌了以后,这个请求才能被处理,如果没有拿到令牌,那么这个请求就会进行等待,或者会直接被丢弃掉。

        具体的计算方式就是,在请求进入到桶内的时候,会根据当前的时间,假设我们桶每秒能产生5个令牌,此时进入桶的时间在第0.2秒进来的,此时桶内刚好生成了一个令牌,那么这个请求就能被处理了。在有些时候,一秒内产生的令牌没有被全部耗尽,假设剩余3个,那么下一秒进来的请求就会优先消耗之前生成到了令牌,当然,这个时候我们桶内也同时在产生令牌。下面举个例子:

        某一时间,刚好同时进来了5个请求,我们的令牌一开始刚好剩5个,令牌是刚好够用的。后面进来的请求对应我们的令牌桶,有令牌了就拿到令牌,进行处理,如果没有,那么就丢弃。

       如果我们一开始并没有进来请求,令牌刚好剩3三个,前面0.4秒没有请求,桶内有5个令牌。在第0.6内,还是没有进来请求,那么这个产生的令牌就被丢弃了。后续有请求进来,那么就消费令牌,没有的话就丢弃令牌。

        那么这是不是意味着,我们让我们的令牌桶的数量越多越好?当然不是的,实际中我们要考虑我们服务处理QPS的能力,如果一秒内最多承受5次请求的时候,那么我们设置为3个令牌就好了,这样子就能够比较平滑地处理我们的业务,也不会因为请求的猛增而导致我们服务的宕机,是能够比较平稳地处理我们的请求的。(Gateway实现的限流算法也是基于Redis实现令牌桶算法)

2.2.2 图示

        

2.2.3 运用

        Sentinel 在 WarmUpController ,也就是热点参数限流中运用到了令牌桶算法,在这里可以实现对系统的预热,设定预热时间和水位线,对于预热期间多余的请求直接拒绝掉。

2.2.4 总结

         令牌桶算法,是一种比较常见的限流算法,它能可以容忍一定突发流量,在很多地方都有运用到。

优点:在请求量持续高于令牌生成速度的时候比较平滑,基本能保证流量的稳定性。并且根据桶内积累的令牌可以应对突增的流量,对于流量控制的精确度高。

缺点:请求量在令牌生成速率上下波动的时候,无法保证曲线的平滑。

2.3 漏桶算法

2.3.1 介绍

        漏桶算法,和令牌桶算法一样,也是存在一个抽象的桶,其实也是一个容器。在这个容器里面,当有请求进来的时候,会将每一个请求都当做"水滴"一样放入到"漏桶"中,而漏桶就以美妙固定的速率向外"漏"处请求来执行。如果"漏桶"空了,那么就停止漏水,此时就是没有请求的情况。如果"漏桶"满了,那么后面进来的请求,就会被直接丢弃。

        漏桶算法的视线是基于一个消息队列来实现的。假如每个请求的耗时为200ms,而我们的消息队列最多能处理2000ms的请求,那么在队列没有满的时候,也就是请求少于10个的时候,每进来一个请求都会被放到我们的队列当中,等到前面的请求都被处理完了,就会处理该请求了。

        而如果此时刚好队列里面有10个请求,我们的队列已经达到了处理的极限,后面每个请求进来都会被丢弃,直到有请求被处理完了,队列有空余的位置,这是才能接收一些请求放进队列中,一旦满了就会重复上述的操作。

2.3.2 图示

2.3.3 运用

        排队等待的限流模式则基于漏桶算法。

2.3.4 总结

        漏桶算法的实现思想也不难,还是基于桶这个容器的概念,根据桶内是否容量来存储"水滴"来判断是否将"水滴"放入到桶内。

优点:使用漏桶算法能使我们的请求以恒定的速度进行放行,是决定的平滑,并且它能够处理流量突增的情况,对流量的控制比较高。

缺点:在某些场景中,漏桶算法并不能有效的使用网络资源,因为漏桶的漏出速率是相对固定的,所以在网络情况比较好并且没有拥塞的状态下,漏桶依然是会有限制的,并不能放开量,因此并不能有效的利用网络资源。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值