sentinel中的资源类,可以通过注解SentinelResource指定资源,具体的资源类是ResourceWrapper,包装了name和entryType属性,用户可以为需要保护的对象创建一个资源类,然后再配置相对于的规则就可以实现对资源的保护,同时资源和规则是解耦的,而且规则可以在运行时进行修改
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
重要属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名 | |
count | 限流阈值 | |
grade | 限流阈值类型,QPS 或线程数模式 | QPS 模式 |
limitApp | 流控针对的调用来源 | default,代表不区分调用来源 |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 | 直接拒绝 |
同一个资源可以同时有多个限流规则
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
rule1.setResource(resource);
// Set max qps to 20
rule1.setCount(20);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
重要属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,即规则的作用对象 | |
grade | 熔断策略,支持慢调用比例/异常比例/异常数策略 | 慢调用比例 |
count | 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值 | |
timeWindow | 熔断时长,单位为 s | |
minRequestAmount | 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) | 5 |
statIntervalMs | 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) | 1000 ms |
slowRatioThreshold | 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入) |
同一个资源可以同时有多个降级规则。
private static void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule(resource);
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
.setCount(0.7); // Threshold is 70% error ratio
.setMinRequestAmount(100)
.setStatIntervalMs(30000) // 30s
.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统规则包含下面几个重要的属性:
Field | 说明 | 默认值 |
---|---|---|
highestSystemLoad | load1 触发值,用于触发自适应控制阶段 | -1 (不生效) |
avgRt | 所有入口流量的平均响应时间 | -1 (不生效) |
maxThread | 入口流量的最大并发数 | -1 (不生效) |
qps | 所有入口资源的 QPS | -1 (不生效) |
highestCpuUsage | 当前系统的 CPU 使用率(0.0-1.0) | -1 (不生效) |
很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的访问控制(黑白名单)的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
授权规则,即黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:
属性 | 说明 | 默认值 |
---|---|---|
resource | 资源名 | |
count | 限流阈值 | |
grade | 限流模式 | QPS 模式 |
durationInSec | 统计窗口时间长度(单位为秒) | 1s |
controlBehavior | 流控效果(支持快速失败和匀速排队模式) | 快速失败 |
maxQueueingTimeMs | 最大排队等待时长(仅在匀速排队模式生效) | 0ms |
paramIdx | 热点参数的索引,必填,对应 SphU.entry(xxx, args) 中的参数索引位置 | |
paramFlowItemList | 参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面 count 阈值的限制。仅支持基本类型和字符串类型 | |
clusterMode | 是否是集群参数流控规则 | false |
clusterConfig | 集群流控相关配置 |
属性 | 说明 | 默认值 |
---|---|---|
resource | 资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称 | |
resourceMode | 规则是针对 API Gateway 的 route,还是用户在 Sentinel 中定义的 API 分组 | 默认是 route |
grade | 限流模式 | QPS 模式 |
count | 限流阈值 | |
intervalSec | 统计时间窗口,单位是秒 | 1 |
controlBehavior | 流量整形的控制效果,目前支持快速失败和匀速排队两种模式,默认是快速失败。 | 快速失败 |
burst | 应对突发请求时额外允许的请求数目 | |
maxQueueingTimeoutMs | 匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效 | |
paramItem | 参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则 |
paramItem参数说明
源码中可以看到解释
/** * This class holds metadata of current invocation:
* **
*- the {@link EntranceNode}: the root of the current invocation * tree.
*- the current {@link Entry}: the current invocation point.
*- the current {@link Node}: the statistics related to the * {@link Entry}.
*- the origin: The origin is useful when we want to control different * invoker/consumer separately. Usually the origin could be the Service Consumer's app name * or origin IP.
*
* Each {@link SphU}#entry() or {@link SphO}#entry() should be in a {@link Context}, * if we don't invoke {@link ContextUtil}#enter() explicitly, DEFAULT context will be used. * A invocation tree will be created if we invoke {@link SphU}#entry() multi times in * the same context. * Same resource in different context will count separately, see {@link NodeSelectorSlot}. */
Context 代表调用链路上下文,贯穿一次调用链路中的所有 Entry, Context 是通过 ThreadLocal 维护的,在异步调用时会丢失context,它维护着当前调用链路的元数据,这个类包含了以下几个核心属性
每次通过SphU.entry()或SphO.entry()时都需要在一个上下文中调用,如果没有则会使用一个默认的context,在一个上下文中多次调用SphU.entry()将会创建一个调用树,不同上下文中的相同资源将单独计数,这个就体现在NodeSelectorSlot类中有一个Map保存了DefaultNode,其中的key就是context的name。也就是不同的上线文对应不同的DefaultNode,针对相同资源会单独统计。
官方解释是
This class holds information of current invocation
每次资源调用都会创建一个 Entry,这个类包含了当前调用的信息,每次执行SphU.entry()时候如果能正常返回一个entry对象,则表示受保护的资源可以正常访问,否则会抛出一个BlockException标识发生限流。该类包含以下几个属性
node是sentinel中的核心概念,sentinel中主要有几种node类型
StatisticNode就是通过metric类进行数据统计的,他本身只是一层封装,底层还是通过window滑动窗口统计,具体实现是ArrayMetric
翻译过来就是槽位的意思,slot是sentinel中非常重要的一个概念,这个就是责任链模式的体现,sentinel的工作流程就是围绕着一个个插槽所组成的插槽链来展开的。需要注意的是每个插槽都有自己的职责,他们各司其职完好的配合,通过一定的编排顺序,来达到最终的限流降级的目的。默认的各个插槽之间的顺序是固定的,因为有的插槽需要依赖其他的插槽计算出来的结果才能进行工作但是这并不意味着我们只能按照框架的定义来,sentinel 通过 SlotChainBuilder
作为 SPI 接口,使得 Slot Chain 具备了扩展的能力。我们可以通过实现 SlotsChainBuilder
接口加入自定义的 slot 并自定义编排各个 slot 之间的顺序,从而可以给 sentinel 添加自定义的功能。同时同一个资源会全局共享一个SlotChain执行链。