前言
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。通过限流可以保证使用有限的资源提供最大化的服务能力,按照预期流量提供服务,超出的部分将会拒绝服务、等待排队或降级处理。Sentinel是一个面向分布式、多语言异构化服务架构的流量治理组件,通过对其源码级别的学习,能够很好地去了解限流的模式和原理,也可以学到一些比较优秀的设计思想。
两个重要概念
Sentinel的核心功能就是通过根据可配置的资源保护规则来保护指定的资源。
这里有两个核心概念:资源和规则。
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
流控规则
- grade:流控级别。0(FLOW_GRADE_THREAD)表示根据线程数进行流控,1(FLOW_GRADE_QPS)表示根据qps进行流控。
- count:流控的阈值。qps或者线程数
- strategy:流控策略。
- 0(STRATEGY_DIRECT):根据调用方限流。限流规则中的limitApp 字段用于根据调用方进行流量控制。该字段的值有以下三种选项,分别对应不同的场景:
- default:表示不区分调用者,来自任何调用者的请求都将进行限流统计。
- other:表示针对除 {some_origin_name} 以外的其余调用方的流量进行流量控制。
- {some_origin_name}:表示针对特定的调用者,只有来自这个调用者的请求才会进行流量控制。
- 1(STRATEGY_RELATE):具有关系的资源流量控制,关联流量控制。当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。可使用关联限流来避免具有关联关系的资源之间过度的争抢。
- 2(STRATEGY_CHAIN):根据调用链路入口限流,链路限流。Sentinel 允许只根据某个入口的统计信息对资源限流。调用链的入口是通过 API 方法 ContextUtil.enter(name) 定义的。
- 0(STRATEGY_DIRECT):根据调用方限流。限流规则中的limitApp 字段用于根据调用方进行流量控制。该字段的值有以下三种选项,分别对应不同的场景:
- refResource:strategy为STRATEGY_RELATE时,指定关联资源。
- controlBehavior:流控的手段。
- 0(CONTROL_BEHAVIOR_DEFAULT):直接拒绝。当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。
- 1(CONTROL_BEHAVIOR_WARM_UP):冷启动。让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。
- 2(CONTROL_BEHAVIOR_RATE_LIMITER):匀速器。让请求以均匀的速度通过,对应的是漏桶算法。
- 3(CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER):冷启动+匀速器。
- warmUpPeriodSec:冷启动时间。
- maxQueueingTimeMs:匀速器最大排队时间。
- controller:流量整形控制器。根据controlBehavior设置对应的控制器。
熔断规则
- grade:熔断级别
- 0(DEGRADE_GRADE_RT):最大响应时间。
- 1(DEGRADE_GRADE_EXCEPTION_RATIO):异常比例。
- 2(DEGRADE_GRADE_EXCEPTION_COUNT):异常数。
- count:在RT模式下,表示最大响应时间,单位毫秒。在exception ratio模式下为0.0-1.0。exception count模式下表示异常数。
- timeWindow:熔断之后的恢复时间。
- minRequestA