结合Alibaba sentinel和guardian谈谈服务器为了保证突发场景下不被打挂而做得策略。其实熔断和降级也是限流的实现方式。

限流

定义:是对某方法、某接口单位时间内的访问次数加以限制,使得超出该限制的访问被丢弃。
常见限流算法:

  1. 固定窗口限流
    设置一个单位时间内的访问数量上限,比如1秒只许访问100次,计数达到100后,之后的访问会被丢弃。到第二个1秒,再去重置计数器。
    缺点是无法解决固定窗口的边界问题,比如第一个窗口右边界附近访问60次,第二个窗口左边界访问60次,虽然两个窗口分别来看都没有达到限流要求,但这个窗口边界附近确实出现了一个流量顶峰。
  2. 滑动窗口限流
    将固定窗口的单位时间细分,比如细分为10格,每过100毫秒,窗口右移一格,只需要保证窗口内的访问次数不超过访问上限即可。因为滑动窗口边界是平滑移动的,所以可以保证每一次窗口的移动都能够限制窗口时间内访问上限。
  3. 漏桶
    使用一个流量整形器,类似一个漏桶,虽然无法得知水流入的速度,但是我们可以控制流出的速度,将流量进行整形之后再打到服务器请求处理的接口上,通过一个漏桶接可以实现请求的稳定打入。但放弃了对突发请求的控制,即便突发情况下请求再多,服务端依然以定速处理。
  4. 令牌桶
    定速产生令牌,令牌总数有上限。请求拿着令牌打到后端,没有令牌就不处理,有令牌就处理。这种方式使得即使有突发请求过来,只要令牌桶还没空,那么服务端就能跟上请求到达的速度去处理。这种方式的限流是通过限制令牌数量上限的方式,若请求速度高于令牌生成速度,因为令牌数量有限,那么很快令牌就会被耗尽,后面拿不到令牌的请求就会被丢弃。guava实现了这种算法,sentinel用得就是这种。

Guardian限流:使用令牌桶算法,依赖DRM,即配置中心,Guardian Console推送限流配置至DRM,DRM推送至应用端。
限流范围:某rest接口、某方法、RPC调用。
限流指标:支持以调用数、堆内存使用量、并发线程数作为指标来配置限流规则。

集群限流:如果负载均衡效果比较好(各服务器流量比较平均),只需要单机限流也可以。
实现:比如sentinel会根据集群服务器数量,选出1个或数个token server,其他的作为token client,根据集群限流策略统一发放令牌给各个机器,同时配合单机限流兜底策略防止出现流量不均衡单机被打挂。若token server挂掉,那么集群限流失效,退化为单机限流。

熔断

定义:分布式应用的下游服务挂了,为了不把请求继续打到下游服务去导致雪上加霜,本应用自动断开与下游服务的连接,并通过小流量尝试、慢恢复。
Sentinel熔断指标:下游服务的异常数、异常比例、慢调用数(慢调用可通过一个响应时间阈值自定义)。可根据这三个指标来配置熔断策略。
Sentinel熔断步骤:达到熔断阈值后将下游服务连接完全熔断,然后再通过小流量测试下游服务恢复情况,如果恢复了,那么再恢复完全连接。

降级

定义:在短时突发流量场景下,应用为了保证核心功能可用(如支付系统),暂时自动中断边缘性的服务(如浏览、评论)的流量打入,使得服务器能够处理核心请求,免得支付系统混乱造成重大损失,断臂求生,待突发期过了之后再行启用。
降级指标与熔断相同。