sentinel 简介


sentinel以流量为切入点,从流量控制,熔断降级,系统自适应保护,黑白名单控制,热点参数限流,集群限流,网关限流多个维度来保障服务的稳定性.sentinel主要具有以下功能

 

1.流量控制

1.1 配置介绍

sentinel通过用户配置的FlowRule进行流量控制,每个资源都可以配置一个或者多个FlowRule,如果配置了多个FlowRule则sentinel会依次遍历所有的FlowRule直到有FlowRule触发限流或者遍历完所有的规则使请求通过.

每一个FlowRule都有一下参数组成,用户可以组合这些元素来达到自己想要的限流效果

      • resource:资源名,即限流规则的作用对象
      • count: 限流阈值,每秒允许通过的请求的数量
      • grade: 限流阈值类型(QPS 或并发线程数)
      • limitApp: 流控针对的调用来源,若为 default 则不区分调用来源,可以在调用之前使用ContextUtil.enter(name,origin)指定,启动name为当前context的名称,origin为请求来源
      • strategy: 调用关系限流策略,直接限流,关联限流和调用链限流,关联限流需要配合refResource使用,即需要配置一个关联的资源
      • controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队),匀速排队需要
      • maxQueueingTimeMs:匀速排队限流效果的时候队列的最大长度
      • warmUpPeriodSec:warm up 限流效果的时候预热时间.
      • refResource:关联资源的名称

1.2 基于qps/线程数的流量控制

1.2.1 基于qps的流量控制

当QPS超过用户在FlowRule中设置的阈值的时候,sentinel就会根据用户在FlowRule中的配置采取流控措施,包括直接拒绝,warn up,匀速排队.

直接拒绝

这个是sentinel基于QPS的默认的流控措施,如果当前QPS超过了阈值,则对新到来的请求直接拒绝.

warn up:

即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过”冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。当预热完成之后就进行匀速排队的流控措施.

匀速排队:

匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。并且sentinel的匀速排队不支持QPS超过1000的场景.

  1.2.2 基于线程数的流量控制

线程数控制用于保护业务的线程池不会应为慢调用而耗尽.为了避免这种情况发生我们通常使用不同的线程池隔离不同的业务,这种方案虽然隔离性比较好,但是会创建很多线程,线程切换的开销比较大,对于低延迟的调用有较大影响.sentinel的线程数量的控制不负责创建和维护线程池,而是简单的统计当前请求上下文的线程数量,如果超过了阈值就会自动拒绝新到来的请求.

1.3 基于调用关系的流量控制

  1.3.1 调用方限流

ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方名称。这些信息会在 ClusterBuilderSlot 中被统计.

中的 limitApp 字段用于根据调用方进行流量控制。该字段的值有以下三种选项,分别对应不同的场景:

      • default:表示不区分调用者,来自任何调用者的请求都将进行限流统计。如果这个资源名的调用总和超过了这条规则定义的阈值,则触发限流。
      • {some_origin_name}:表示针对特定的调用者,只有来自这个调用者的请求才会进行流量控制。例如 NodeA 配置了一条针对调用者caller1的规则,那么当且仅当来自 caller1 对 NodeA 的请求才会触发流量控制。
      • other:表示针对除 {some_origin_name} 以外的其余调用方的流量进行流量控制。例如,资源NodeA配置了一条针对调用者 caller1 的限流规则,同时又配置了一条调用者为 other 的规则,那么任意来自非 caller1 对 NodeA 的调用,都不能超过 other 这条规则定义的阈值。

同一个资源名可以配置多条规则,规则的生效顺序为:{some_origin_name} > other > default

注意:调用来源的数目不要太多(一般不要超过几百个),否则内存占用会非常多(调用来源的统计节点最大数目=资源数目*来源数目)。

 

1.3.2 调用链路入口限流

NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。

一棵典型的调用树如下图所示:

     	          machine-root
                    /       /
                   /         /
             Entrance1     Entrance2
                /             /
               /               /
      DefaultNode(nodeA)   DefaultNode(nodeA)

上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 strategy 为 RuleConstant.STRATEGY_CHAIN,同时设置 refResource 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而不关心经 Entrance2 到来的调用。

1.3.3 关联限流

当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 strategy 为 RuleConstant.STRATEGY_RELATE 同时设置 refResource 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。

 

2.熔断降级

  2.1 参数配置

    熔断降级的配置规则在DegradeRule中配置,可以配置一下参数

    • resource:资源名,即限熔断降级的作用对象
    • grade: 熔断策略,支持慢调用比例/异常比例/异常数策略
    • count: 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
    • timeWindow: 熔断时长,单位为秒
    • minRequestAmount: 熔断触发的最小请求数量,少于这个数量则不会触发熔断.
    • statIntervalMs:统计时长,单位为毫秒,默认为1000ms
    • warmUpPeriodSec:warm up 限流效果的时候预热时间.
    • slowRatioThreshold:慢调用比例阈值,仅慢调用比例模式有效

  2.2  熔断策略

    • 慢调用比例 (SLOW_REQUEST_RATIO)
      选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
    • 异常比例 (ERROR_RATIO)
      当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% – 100%。
    • 异常数 (ERROR_COUNT)
      当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

 

3.系统自适应保护

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

Sentinel 在系统自适应保护的做法是,用 load1 作为启动控制流量的值,而允许通过的流量由处理请求的能力,即请求的响应时间以及当前系统正在处理的请求速率来决定。

3.1 配置介绍

系统自适应保护的规则在SystemRule中配置,可以配置一下参数

 

    • highestSystemLoad:(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5
    • highestCpuUsage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
    • avgRt:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
    • maxThread:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
    • QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护

 

 

4.来源访问控制

有时候我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。调用方信息通过 ContextUtil.enter(resourceName, origin) 方法中的 origin 参数传入。

4.1 参数配置

黑白名单规则(AuthorityRule)非常简单,主要有以下配置项

    • resource:需要保护的资源名称
    • limitApp:访问的来源名称,如果有多个来源则使用逗号分割,eg:appA,appB
    • strategy:保护的策略,白名单/黑名单.AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式

 

5.热点参数限流

 

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

 

    • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
    • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

 

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。要使用热点参数限流功能,需要引入sentinel-parameter-flow-control依赖.

5.1.参数配置

热点参数规则在ParamFlowRule中配置,类似于FlowRule

 

    • resource:资源名称,必填.
    • count:限流阈值,必填,
    • grade :限流模式:QPS或者线程数量.默认为QPS
    • durationInSec:统计窗口时间长度,单位为秒.默认1s,
    • controlBehavior:流控效果,支持快速失败和匀速排毒.默认为快速失败
    • maxQueueingTimeMs:最大排队等待时长,仅在匀速排队模式的时候生效,默认为0ms
    • paramIdx:热点参数的索引,必填,即在SphU.entry中掺入的args的索引位置.
    • paramFlowItemList:参数例外想,可以只针对指定的参数值打暗渡设置限流阈值,不受上面配置的影响.
    • clusterMode:是否是集群参数流控规则.默认为false
    • clusterConfig:集群流控香相关配置.

 

 

6.集群限流

集群流控还可以解决流量不均匀导致总体限流效果不佳的问题。假设集群中有 10 台机器,我们给每台机器设置单机限流阈值为 10 QPS,理想情况下整个集群的限流阈值就为 100 QPS。不过实际情况下流量到每台机器可能会不均匀,会导致总量没有到的情况下某些机器就开始限流。因此仅靠单机维度去限制的话会无法精确地限制总体流量。而集群流控可以精确地控制整个集群的调用总量,结合单机限流兜底,可以更好地发挥流量控制的效果

 

集群流控中共有两种身份:

 

    • Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。
    • Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)

 

  

Sentinel 引入了集群流控模块,主要包含以下几部分:

 

    • sentinel-cluster-common-default: 公共模块,包含公共接口和实体
    • sentinel-cluster-client-default: 默认集群流控 client 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展
    • sentinel-cluster-server-default: 默认集群流控 server 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展;同时提供扩展接口对接规则判断的具体实现(TokenService),默认实现是复用 sentinel-core 的相关逻辑

 

  6.1 规则配置

FlowRule 添加了两个字段用于集群限流相关配置:

 

    • clusterMode : 是否为集群模式
    • ClusterFlowConfig:集群限流模式相关配置
      • flowId 代表全局唯一的规则 ID,Sentinel 集群限流服务端通过此 ID 来区分各个规则,因此务必保持全局唯一。一般 flowId 由统一的管控端进行分配,或写入至 DB 时生成
      • thresholdType 代表集群限流阈值模式。其中单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据客户端对应的 namespace(默认为 project.name 定义的应用名)下的连接数来计算总的阈值(比如独立模式下有 3 个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为 30);而全局模式下配置的阈值等同于整个集群的总阈值。

 

  6.2 客户端配置

在clusterClientConfig中配置

    • serverHost: token server host
    • serverPort: token server 端口
    • requestTimeout: 请求的超时时间(默认为 20 ms)

  6.3  服务端配置

在ClusterServerConfig中配置

    • namespace set: 集群限流服务端服务的作用域(命名空间),可以设置为自己服务的应用名。集群限流 client 在连接到 token server 后会上报自己的命名空间(默认为 project.name 配置的应用名),token server 会根据上报的命名空间名称统计连接数。
    • transport config: 集群限流服务端通信相关配置,如 server port
    • flow config: 集群限流服务端限流相关配置,如滑动窗口统计时长、格子数目、最大允许总 QPS等

  6.4 启动方式

 

    Sentinel 集群限流服务端有两种启动方式:

 

    • 独立模式(Alone),即作为独立的 token server 进程启动,独立部署,隔离性好,但是需要额外的部署操作。独立模式适合作为 Global Rate Limiter 给集群提供流控服务。

 

image

 

    • 嵌入模式(Embedded),即作为内置的 token server 与服务在同一进程中启动。在此模式下,集群中各个实例都是对等的,token server 和 client 可以随时进行转变,因此无需单独部署,灵活性比较好。但是隔离性不佳,需要限制 token server 的总 QPS,防止影响应用本身。嵌入模式适合某个应用集群内部的流控。

 

image

 

sentinel提供了 API 用于在 embedded 模式下转换集群流控身份:http://<ip>:<port>/setClusterMode?mode=<xxx>

 

其中 mode 为 0 代表 client,1 代表 server,-1 代表关闭。注意应用端需要引入集群限流客户端或服务端的相应依赖。

 

在独立模式下,我们可以直接创建对应的 ClusterTokenServer 实例并在 main 函数中通过 start 方法启动 Token Server。

 

7.网关限流

 

Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑:

 

  • GatewayFlowRule:网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。
  • ApiDefinition:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫 my_api,请求 path 模式为 /foo/** 和 /baz/** 的都归到 my_api 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。

 

7.1 参数配置

网关限流规则配置在网关限流规则 GatewayFlowRule中.

    • resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
    • resourceMode:规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)还是用户在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是 route。
    • grade:限流指标维度,同限流规则的 grade 字段。
    • count:限流阈值
    • intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
    • controlBehavior:流量整形的控制效果,同限流规则的 controlBehavior 字段,目前支持快速失败和匀速排队两种模式,默认是快速失败。
    • burst:应对突发请求时额外允许的请求数目。
    • maxQueueingTimeoutMs:匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。
    • paramItem:参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。其中的字段:
      • parseStrategy:从请求中提取参数的策略,目前支持提取来源 IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意 Header(PARAM_PARSE_STRATEGY_HEADER)和任意 URL 参数(PARAM_PARSE_STRATEGY_URL_PARAM)四种模式。
      • fieldName:若提取策略选择 Header 模式或 URL 参数模式,则需要指定对应的 header 名称或 URL 参数名称。
      • pattern:参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控;若为空则统计该请求属性的所有值。(1.6.2 版本开始支持)
      • matchStrategy:参数值的匹配策略,目前支持精确匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正则匹配(PARAM_MATCH_STRATEGY_REGEX)。(1.6.2 版本开始支持)

用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则,或通过 GatewayRuleManager.register2Property(property) 注册动态规则源动态推送(推荐方式)。

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/267729.html

(0)
上一篇 2022年6月18日
下一篇 2022年6月18日

相关推荐

发表回复

登录后才能评论