​FlowSlot​ 会根据预设的规则,结合前面 ​NodeSelectorSlot​​ClusterBuilderSlot​​StatisticSlot​ 统计出来的实时信息进行流量控制。

限流的直接表现是在执行 ​Entry nodeA = SphU.entry(resourceName)​ 的时候抛出 ​FlowException​ 异常。​FlowException​ 是 ​BlockException​ 的子类,您可以捕捉 ​BlockException​ 来自定义被限流之后的处理逻辑。

服务保障中间件 Sentinel  02 限流_限流

基于QPS/并发数的流量控制

2.1 并发线程数控制

并发数控制用于保护业务线程池不被慢调用耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。

2.2 QPS流量控制

当 QPS 超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:直接拒绝Warm Up匀速排队​。对应 ​​FlowRule​​​ 中的 ​​controlBehavior​​ 字段。

直接拒绝​RuleConstant.CONTROL_BEHAVIOR_DEFAULT​)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出​FlowException​。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。具体的例子参见 ​FlowQpsDemo​

Warm Up(​RuleConstant.CONTROL_BEHAVIOR_WARM_UP​)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮

服务保障中间件 Sentinel  02 限流_线程池_02

默认 ​coldFactor​ 为 3,即请求 QPS 从 ​threshold / 3​ 开始,经预热时长逐渐升至设定的 QPS 阈值。

服务保障中间件 Sentinel  02 限流_线程池_03

匀速排队

匀速排队(​​RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER​​)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

服务保障中间件 Sentinel  02 限流_流量控制_04

服务保障中间件 Sentinel  02 限流_线程池_05


集群流控

服务保障中间件 Sentinel  02 限流_流量控制_06

服务保障中间件 Sentinel  02 限流_流量控制_07

漏桶算法与令牌桶算法在表面看起来类似,很容易将两者混淆。但事实上,这两者具有截然不同的特性,且为不同的目的而使用。

漏桶算法与令牌桶算法的区别在于

l 漏桶算法能够强行限制数据的传输速率。

l 令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。需要说明的是:在某些情况下,漏桶算法不能够有效地使用网络资源。因为漏桶的漏出速率是固定的,所以即使网络中没有发生拥塞,漏桶算法也不能使某一个单独的数据流达到端口速率。因此,漏桶算法对于存在突发特性的流量来说缺乏效率。而令牌桶算法则能够满足这些具有突发特性的流量。通常,漏桶算法与令牌桶算法结合起来为网络流量提供更高效的控制。

服务保障中间件 Sentinel  02 限流_流量控制_08

服务保障中间件 Sentinel  02 限流_线程池_09

服务保障中间件 Sentinel  02 限流_线程池_10

并不能说明令牌桶一定比漏洞好,她们使用场景不一样。令牌桶可以用来保护自己,主要用来对调用者频率进行限流,为的是让自己不被打垮。所以如果自己本身有处理能力的时候,如果流量突发(实际消费能力强于配置的流量限制),那么实际处理速率可以超过配置的限制

而漏桶算法,这是用来保护他人,也就是保护他所调用的系统。主要场景是,当调用的第三方系统本身没有保护机制,或者有流量限制的时候,我们的调用速度不能超过他的限制,由于我们不能更改第三方系统,所以只有在主调方控制。这个时候,即使流量突发,也必须舍弃。因为消费能力是第三方决定的。

总结起来:如果要让自己的系统不被打垮,用令牌桶。如果保证被别人的系统不被打垮,用漏桶算法

漏桶算法和令牌桶算法的区别

漏桶算法的出水速度是恒定的,那么意味着如果瞬时大流量的话,将有大部分请求被丢弃掉(也就是所谓的溢出)。漏桶算法通常可以用于限制访问外部接口的流量,保护其他人系统,比如我们请求银行接口,通常要限制并发数。

令牌桶算法生成令牌的速度是恒定的,而请求去拿令牌是没有速度限制的。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌,可以处理瞬时流量,而且拿令牌的过程并不是消耗很大的事情。令牌桶算法通常可以用于限制被访问的流量,保护自身系统。

令牌桶算法有个桶的请求存量,能够处理瞬时大流量

服务保障中间件 Sentinel  02 限流_限流_11