Sentinel浅析

1 修改历史

2 概述

2.1 术语

2.2 背景

随着用户量越来越大,服务偶尔会出现满负荷运行,极端情况下服务OOM或者假死需要很久才能恢复正常,如果重启可能会瞬间CPU飙升,使响应时间增长,影响用户体验,应该尽量避免,所以引入限流拒绝请求来降低服务器峰值后的压力。

2.3 目标

车辆、订单、客户、权限、元数据、通用中台都需要接入限流,避免服务器峰值后压力持续增加,导致服务不可用。

 

2.4 接入方式

4 原理剖析

4.1 总体架构

 

 

 

4.2 定义资源

支持手动定义资源、异步以及注解定义

// 手动定义,来源于官网

Entry entry = null;
// 务必保证 finally 会被执行
try {
  // 资源名可使用任意有业务语义的字符串,注意数目不能太多(超过 1K),超出几千请作为参数传入而不要直接作为资源名
  // EntryType 代表流量类型(inbound/outbound),其中系统规则只对 IN 类型的埋点生效
  entry = SphU.entry("自定义资源名");
  // 被保护的业务逻辑
  // do something...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 进行相应的处理操作
} catch (Exception ex) {
  // 若需要配置降级规则,需要通过这种方式记录业务异常
  Tracer.traceEntry(ex, entry);
} finally {
  // 务必保证 exit,务必保证每个 entry 与 exit 配对
  if (entry != null) {
    entry.exit();
  }
}

 

dubbo adapter中使用

//com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter
//统计接口
interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN);
//统计方法
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC,
                EntryType.IN, invocation.getArguments());

4.3 定义规则

Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略。参考:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

 

4.3.1 流量控制(FlowControl)

Field

说明

默认值

resource

资源名,资源名是限流规则的作用对象

 

count

限流阈值

 

grade

限流阈值类型,QPS 模式(1)或并发线程数模式(0)

QPS 模式

limitApp

流控针对的调用来源

default,代表不区分调用来源

strategy

调用关系限流策略:直接、链路、关联

根据资源本身(直接)

controlBehavior

流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流

直接拒绝

clusterMode

是否集群限流

 

4.3.1.1 限流策略

  • STRATEGY_DIRECT:根据调用方进行限流,根据调用方进行限流。ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方的身份。

 

  • STRATEGY_RELATE:根据关联流量限流。当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联,可使用关联限流来避免具有关联关系的资源之间过度的争抢。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。

 

  • STRATEGY_CHAIN:根据调用链路入口限流。假设来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许根据某个入口的统计信息对资源进行限流。

 

4.3.1.2 流控效果(FlowRule)

  • 直接拒绝方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException

 

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

 

 

  • 匀速排队会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。主要用于处理间隔性突发的流量,例如消息队列。

4.3.2 熔断降级规则(DegradeRule)

一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

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 引入)

 

4.3.2.1 熔断策略

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

 

  • 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0],代表 0% - 100%。

 

  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

 

4.3.3 系统保护规则(SystemRule)

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

 

Field

说明

默认值

highestSystemLoad

load1

触发值,用于触发自适应控制阶段

-1 (不生效)

avgRt

所有入口流量的平均响应时间

-1 (不生效)

maxThread

入口流量的最大并发数

-1 (不生效)

qps

所有入口资源的 QPS

-1 (不生效)

highestCpuUsage

当前系统的 CPU 使用率(0.0-1.0)

-1 (不生效)

自适应:应该根据系统能够处理的请求,和允许进来的请求,来做平衡,而不是根据一个间接的指标(系统 load)来做限流。最终我们追求的目标是在系统不被拖垮的情况下,提高系统的吞吐率,而不是 load 一定要到低于某个阈值。Sentinel 在系统自适应保护的做法是,用 load1 作为启动自适应保护的因子,而允许通过的流量由处理请求的能力,即请求的响应时间以及当前系统正在处理的请求速率来决定。TCP BBR

 

4.3.4 来源访问控制规则(AuthorityRule)

根据调用方来限制资源是否通过

 

4.3.5 热点参数规则(ParamFlowRule)

热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。

 

4.3.5.1 热点参数规则(ParamFlowRule)

属性

说明

默认值

resource

资源名,必填

 

count

限流阈值,必填

 

grade

限流模式

QPS 模式

durationInSec

统计窗口时间长度(单位为秒),1.6.0 版本开始支持

1s

controlBehavior

流控效果(支持快速失败和匀速排队模式),1.6.0 版本开始支持

快速失败

maxQueueingTimeMs

最大排队等待时长(仅在匀速排队模式生效),1.6.0 版本开始支持

0ms

paramIdx

热点参数的索引,必填,对应

SphU.entry(xxx, args)

中的参数索引位置

 

paramFlowItemList

参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面

count

阈值的限制。

仅支持基本类型和字符串类型

 

clusterMode

是否是集群参数流控规则

false

clusterConfig

集群流控相关配置

 

 

 

 

4.4 检验规则是否生效

4.4.1 判断限流降级异常

在 Sentinel 中所有流控降级相关的异常都是异常类BlockException的子类

  • 流控异常:FlowException
  • 熔断降级异常:DegradeException
  • 系统保护异常:SystemBlockException
  • 热点参数限流异常:ParamFlowException

 

4.4.2 block事件

可以通过StatisticSlotCallbackRegistryStatisticSlot注册回调函数

public interface ProcessorSlotEntryCallback<T> {

    void onPass(Context context, ResourceWrapper resourceWrapper, T param, int count, Object... args) throws Exception;

    void onBlocked(BlockException ex, Context context, ResourceWrapper resourceWrapper, T param, int count, Object... args);
}

5 对现有系统影响

接入新的基础服务需要分析对现有系统有哪些影响,以及接入方式是否简单。

5.1 性能影响

  • 限流使用单机模式,限流规则都会保存在内存中,使用推模式获取修改规则,只有规则变更时才会触发修改,对系统影响很小。集群模式需要远程获取token,影响稍大。
  • 限流规则是否生效,仅仅影响计数,对CPU影响很小
  • Dashboard通过定时任务10s获取一次客户端的统计数据,客户端需要5s发送一次心跳包保证客户端服务正常

 

5.2 HTTP接口影响

注意点:

  • 由于http限流是针对Servlet filter进行统计限流,Servlet异常处理需要重定向异常页面。
  • SpringBoot需要通过FilterRegistrationBean来进行过滤器设置,可能需要改造以前的filter设置。
  • 具体处理参考com.alibaba.csp.sentinel.adapter.servlet.CommonFilter#doFilter

5.3 Dubbo接口影响

注意点:

  • Dubbo限流也是通过Dubbo consumer及provider端进行统计限流,通过继承DefaultDubboFallback重写异常回调方法来处理异常。
  • 具体处理参考:com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter#invoke

 

 

6 同类组件功能对比

Sentinel

Hystrix

resilience4j

 

隔离策略

信号量隔离(并发控制)

线程池隔离/信号量隔离

信号量隔离

熔断降级策略

基于慢调用比例、异常比例、异常数

基于异常比例

基于异常比例、响应时间

实时统计实现

滑动窗口(LeapArray)

滑动窗口(基于 RxJava)

Ring Bit Buffer

动态规则配置

支持近十种动态数据源

支持多种数据源

有限支持

扩展性

多个扩展点

插件的形式

接口的形式

基于注解的支持

支持

支持

支持

单机限流

基于 QPS,支持基于调用关系的限流

有限的支持

Rate Limiter

集群流控

支持

不支持

不支持

流量整形

支持预热模式与匀速排队控制效果

不支持

简单的 Rate Limiter 模式

系统自适应保护

支持

不支持

不支持

热点识别/防护

支持

不支持

不支持

多语言支持

Java/Go/C++

Java

Java

Service Mesh 支持

支持 Envoy/Istio

不支持

不支持

控制台

提供开箱即用的控制台,可配置规则、实时监控、机器发现等

简单的监控查看

不提供控制台,可对接其它监控系统

 

7 有哪些可以借鉴的编程思想

  • 使用责任链模式DefaultProcessorSlotChain,不同Slot不同处理逻辑
  • 提供很好的框架支持,dubbo、grpc、servlet、zuul、okhttp等
  • 提供很好的扩展接口,用于业务处理自己的逻辑,比如DubboFallback、CommonFilter
  • StatisticNode中LongAdder线程数统计、滑动窗口MetricBucket中LongAdder使用(写多读少)
posted @ 2021-05-15 13:05  水底的土豆  阅读(185)  评论(0编辑  收藏  举报