Sentinel 流控规则详解(下)

简介: Sentinel 流控规则详解

流控效果


当 QPS、线程数超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:直接拒绝Warm Up匀速排队


直接拒绝


直接拒绝RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException 这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。


Warm up


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


通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:


sentinel 控制台-流控预热过程.png

2018-04-1914:03:46

passqps:480.0

2.Atterthewarm-upperiod.thesystembeginstoprocessthe

samenumberofrequestsasdefinedbythees

I.Thesysemhasbeenidleforawhileandalargenumberofrequestshave

arrived

blockgps

passgps


默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。


规则设置如下图所示:


sentinel 控制台-流控预热规则配置.png

新增流控规则

资源名

lgetStockDetail

针对来源

default

阅值类型

单机关值

100

线程数

QPS

是否集群

流控模式

关联

链路

直接

流控效果

快速失败

排队等待

WarmUp

120

预热时长

关闭高级选项

新增

新增并继续添加

取消


通过 Jmeter 请求过后,可以看到如下效果,完成流控


sentinel 控制台-流控预热过程监控.png

GEThttp://stock-serce/getStockDeail

50

响应时间(ms)

通过QPS

时间

拒绝QPS

40

16.0

1.0

2021-05-1617:26:2

17:27:22

0.0

5

通过QPS

30

0.0

8.0

17:27:12

41.0

拒绝QPS

20

0.0

17:27:11

7.0

33.0

10

0.0

8.0

28.0

17:27:10

17:27:09

24.0

11.0

0.0

17:26

17:26

17:23

17:25

17:24

17:24

17:27:08

7.0

0.0

23.0

拒绝QPS

通过QPS


匀速排队


匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。




这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。


注意:匀速排队模式暂时不支持 QPS > 1000 的场景。


规则设置如下图所示:


sentinel 控制台-流控匀速排队10 秒.png

编辑流控规则

资源名

TgetStockDetail

针对来源

default

闹值类型

单机闽值

100

线程数

QPS

是否集群

流控模式

O关联

链路

直接

流控效果

快速失败

排队等待

WarmUp

10

超时时间

关闭高级选项

保存

取消


然后我们通过 jmeter 请求过后可以看到如下效果:


sentinel 控制台-流控匀速排队监控.png

俱实时监控

关键字

开序

TgetStockDetail

1600

通过QPS

拒绝QPS

响应时间(ms)

时间

1400

1200

0.0

17:23:51

12.0

15.0

1000

17:23:50

2021-05-1617:22:01

20.0

0.0

15.0

800

通过QPS

100

600

0.0

17:23:49

15.0

19.0

55

拒绝QPS

400

0.0

15.0

21.0

17:23:48

200

0

0.0

17:23:47

14.0

20.0

17:20

17:19

17:20

17:21

17:23

17:22

15.0

0.0

20.0

17:23:46

通过QPS

拒绝QPS


4. 降级规则


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


熔断降级策略


Sentinel 提供以下几种熔断策略:


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

我们可以在控制台配置:

sentinel 控制台-流控降级配置.png

编辑降级规则

资源名

igetStockDetail

O异常比例

熔断策略

慢调用比例

0异常数

比例闹值

0.1

最大RT

10

5

最小请求数

10

熔断时长

s

取消

保存

jmeter 模拟请求

sentinel 控制台-流控降级效果.png

127.0.0.1

("code":102,"message":"服务降级了""data"


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


我们可以在控制台配置:


sentinel 控制台-流控降级-异常比率.png

新增降级规则

资源名

lgetStockDetail

熔断策略

异常比例

异常数

慢调用比例

比例间值

0.1

5

5

熔断时长

最小请求数

s

取消

新增

新增并继续添加


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


我们可以在控制台配置:


sentinel 控制台-流控降级-异常数.png

新增降级规则

资源名

lgetStockDetail

熔断策略

慢调用比例

异常数

异常比例

异常数

0.1

熔断时长

5

最小请求数

5

新增

取消

新增并继续添加


熔断降级说明


熔断降级规则(DegradeRule)包含下面几个重要的属性:

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



5. 热点规则


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


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


热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。


sentinel 控制台-热点规则原理.png

QPS:5,blocked

热点,

-

param:axb

请求

param:abo

热点,QPS:3,pass

Sentinel

resA

热点限流

param.xs

非热点,QPS:10,

pass

QPS:5


Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。


热点规则配置需要注意:


1. 首先资源必须是通过 @SentinelResource 申明


2. 参数类型必须是基础数据类型, 否则配置无效


热点规则配置如下图所示:


sentinel 控制台-热点规则配置.png

编辑热点规则

资源名

lgetStockDetail

限流模式

QPS模式

0

参数索引

统计窗口时长

单机闽值

10

10

是否集群

高级选项

保存

取消


注意:资源名称要和 @SentinelResource  中的资源名称对应才能生效


控制器类的代码如下所示:


@SentinelResource(value = "ResOrderGet",
                  fallback = "fallback",
                  fallbackClass = SentinelExceptionHandler.class,
                  blockHandler = "blockHandler",
                  blockHandlerClass = SentinelExceptionHandler.class
                 )
@GetMapping("/order/get/{id}")
public CommonResult<StockModel> getStockDetails(@PathVariable Integer id) {
  StockModel stockModel = new StockModel();
  stockModel.setCode("STOCK==>1000");
  stockModel.setId(id);
  return CommonResult.success(stockModel);
}
// 异常处理类
public class SentinelResourceExceptionHandler {
    //限流熔断业务逻辑
    public static CommonResult<StockModel> blockHandler(@PathVariable Integer id) {
        return CommonResult.error(null, -100, "系统错误 (限流熔断业务逻辑)");
    }
    //异常降级业务逻辑
    public static CommonResult<StockModel> fallback(@PathVariable Integer id) {
        return CommonResult.error(null, -100, "系统错误 (异常降级业务逻辑)");
    }
}


返回异常信息:


sentinel 控制台-热点参数流控降级.png

127.0.0.1:8066/order/get/3

1/20210516184336

m/h

http://127.0.0.1:8066/order/get/3

4

5

-100

"code"

0100

"系统错误(异常降级业务逻辑)",

"message"

"data":null


6 授权规则


很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。


调用方信息通过 ContextUtil.enter(resourceName, origin) 方法中的 origin 参数传入。


Sentinel提供了 RequestOriginParser 接口来处理访问来源,Sentinel保护的资源如果被访问,就会调用 RequestOriginParser解析访问来源。


// 注意导包
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import javax.servlet.http.HttpServletRequest;
public class SentinelRequestOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        return request.getParameter("origin");
    }
}


修改 Config 配置信息


@Configuration
public class FilterContextConfig {
    @Bean
    public FilterRegistrationBean sentinelFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CommonFilter());
        registration.addUrlPatterns("/*");
        // 入口资源关闭聚合
        registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
        registration.setName("sentinelFilter");
        registration.setOrder(1);
        // CommonFilter 的 BlockException 自定义处理逻辑
        WebCallbackManager.setUrlBlockHandler(new SentinelFlowHandler());
        //解决授权规则不生效的问题
        //com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser
        WebCallbackManager.setRequestOriginParser(new SentinelRequestOriginParser());
        return registration;
    }
}


规则配置


sentinel 控制台-授权配置.png

编辑授权规则

资源名

igetOrderDetail

流控应用

order

授权类型

白名单

黑名单

保存

取消


执行请求

正常通过


sentinel 控制台-授权通过.png

6>C

127.0.0.1:8066/getorderDetail?originorder

120210516205223

1

/http://127.0.0.1:8066/getordeetai?oriqin-od

F

寸LC0100

"id":1,

"code":"100-1000-x.yz",

"stockModei":null


异常不通过

sentinel 控制台-授权不通过.png

127.0.0.1:8066/getorderDetail?originode

HNm寸5no

120210516205153

/http://127.0.0.1:8066/getorderDeail?origin-oder

4

"code"

105

"message":"授权规则不通过",

100

nul'

"data":



7 系统规则


系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。


系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。


系统规则支持以下的模式:


  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。


原理


如下图所示


sentinel 控制台-系统规则-原理.png


我们把系统处理请求的过程想象为一个水管,到来的请求是往这个水管灌水,当系统处理顺畅的时候,请求不需要排队,直接从水管中穿过,这个请求的RT是最短的;反之,当请求堆积的时候,那么处理请求的时间则会变为:排队时间 + 最短处理时间。


  • 推论一: 如果我们能够保证水管里的水量,能够让水顺畅的流动,则不会增加排队的请求;也就是说,这个时候的系统负载不会进一步恶化。


我们用 T 来表示(水管内部的水量),用RT来表示请求的处理时间,用P来表示进来的请求数,那么一个请求从进入水管道到从水管出来,这个水管会存在 P * RT 个请求。换一句话来说,当 T ≈ QPS * Avg(RT) 的时候,我们可以认为系统的处理能力和允许进入的请求个数达到了平衡,系统的负载不会进一步恶化。


接下来的问题是,水管的水位是可以达到了一个平衡点,但是这个平衡点只能保证水管的水位不再继续增高,但是还面临一个问题,就是在达到平衡点之前,这个水管里已经堆积了多少水。如果之前水管的水已经在一个量级了,那么这个时候系统允许通过的水量可能只能缓慢通过,RT会大,之前堆积在水管里的水会滞留;反之,如果之前的水管水位偏低,那么又会浪费了系统的处理能力。


  • 推论二: 当保持入口的流量是水管出来的流量的最大的值的时候,可以最大利用水管的处理能力。


然而,和 TCP BBR 的不一样的地方在于,还需要用一个系统负载的值(load1)来激发这套机制启动。


注:这种系统自适应算法对于低 load 的请求,它的效果是一个“兜底”的角色。对于不是应用本身造成的 load 高的情况(如其它进程导致的不稳定的情况),效果不明显。


配置页面


sentinel 控制台-系统流控规则配置.png

新增系统保护规则

阅值类型

OLOADORTO线程数O入口QPSO.CPU使用率

1000

闹值

新增

取消


触发流控规则

sentinel 控制台-系统规则触发流控.png

127.0.0.1:8066/getorderDetail?originorder

HNm

120210516211223

//http://127.0.0.1:8066/getorderDetai?originorde

f

4

LO0100

"code":104,

"message":"系统规则(负载/...不满足要求)",

"data":nul'


8 集群流控


为什么要使用集群流控呢?假设我们希望给某个用户限制调用某个 API 的总 QPS 为 50,但机器数可能很多(比如有 100 台)。这时候我们很自然地就想到,找一个 server 来专门来统计总的调用量,其它的实例都与这台 server 通信来判断是否可以调用。这就是最基础的集群流控的方式。


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


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


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


规则推送


Sentinel 控制台同时提供简单的规则管理以及推送的功能。规则推送分为 3 种模式,包括 "原始模式"、"Pull 模式" 和"Push 模式"。


这里先简单的介绍"原始模式"。


规则管理


您可以在控制台通过接入端暴露的 HTTP API 来查询规则。



sentinel 控制台-普通模式.png

Sentinel控制台1.8.0

注销

应用名

搜索

新增流控规则

order-service

首页

(1/1)

order-service

流换规则

刷新

关键字

172.20.10.3:8720

L实时监控

贺值

流控效果

资源名

流控模式

门值类型

阁值横式

操作

来源应用

旗点链路

直接

单机

OPS

快速失败

test1

default

开除

编辑

流控规则

降级规则

共1条记录每页

条记录

10

小热点规则

系统规则

授权规则

集群流控

机器列表

(1/2)

stock-service

规则推送


sentinel 控制台增加流控规则.png

新增流控规则

资源名

/hello

针对来源

default

单机闻值

阁值类型

单机闽值

线程数

QPS

是否集群

高级选项

新增并继续添加

取消

新增


目前控制台的规则推送也是通过 规则查询更改 HTTP API 来更改规则。这也意味着这些规则仅在内存态生效,应用重启之后,该规则会丢失。


注:若通过控制台推送规则时出现 invalid type 或 empty type 的错误,请确保 transport 模块版本与 core 模块版本保持一致;若控制台版本 >= 1.7.1,请将接入端的相关依赖也升级至 1.7.1 及以上版本。


以上是原始模式。当了解了原始模式之后,我们非常鼓励您通过 动态规则 并结合各种外部存储来定制自己的规则源。我们推荐通过动态配置源的控制台来进行规则写入和推送,而不是通过 Sentinel 客户端直接写入到动态配置源中。在生产环境中,我们推荐 push 模式,具体可以参考:在生产环境使用 Sentinel。


注:若要使用集群流控功能,则必须对接动态规则源,否则无法正常使用。您也可以接入 AHAS Sentinel 快速接入全自动托管、高可用的集群流控能力。


Sentinel 同时还提供应用维度规则推送的示例页面(流控规则页面,前端路由为 /v2/flow),用户改造控制台对接配置中心后可直接通过 v2 页面推送规则至配置中心。Sentinel 抽取了通用接口用于向远程配置中心推送规则以及拉取规则:


  • DynamicRuleProvider<T>: 拉取规则(应用维度)
  • DynamicRulePublisher<T>: 推送规则(应用维度)


用户只需实现 DynamicRuleProviderDynamicRulePublisher 接口,并在 v2 的 controller 中通过 @Qualifier 注解替换相应的 bean 即可实现应用维度推送。我们提供了 Nacos 和 Apollo 的示例,改造详情可参考 应用维度规则推送示例。


鉴权


从 Sentinel 1.5.0 开始,控制台提供通用的鉴权接口 AuthService,用户可根据需求自行实现。


从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。该鉴权能力非常基础,生产环境使用建议根据安全需要自行改造。


sentinel 控制台登录鉴权.png

Sentinel

用户

sentinel

密码

登录

清空


用户可以通过如下参数进行配置:


  • -Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel
  • -Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel
  • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;


同样也可以直接在 Spring properties 文件中进行配置。


注意:部署多台控制台时,session 默认不会在各实例之间共享,这一块需要自行改造。


相关文章
|
7月前
|
监控 API 开发者
Sentinel之道:流控模式解析与深度探讨
Sentinel之道:流控模式解析与深度探讨
183 0
|
7月前
|
Java 数据库连接 Maven
如何使用Sentinel实现流控和降级
通过以上步骤,你可以使用Sentinel实现应用的流量控制和降级操作,以保护系统在高流量或不稳定情况下的稳定性。欢迎关注威哥爱编程,一起学习成长。
122 1
|
3月前
|
监控 Java API
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
先简单介绍熔断、降级等核心概念,然后阐述SpringBoot整合Sentinel的实现方式,最后介绍Sentinel在本项目中的应用。
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
|
5月前
|
监控 算法 Java
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
|
7月前
|
监控 Java 数据安全/隐私保护
Sentinel黑白名单授权规则解读
Sentinel黑白名单授权规则解读
|
7月前
|
监控 数据挖掘 索引
深度剖析Sentinel热点规则
深度剖析Sentinel热点规则
230 1
|
7月前
|
监控 Java API
解密Sentinel中流控规则的阀值奥秘
解密Sentinel中流控规则的阀值奥秘
70 0
|
7月前
|
监控 Java API
数字护盾:深度探讨Sentinel的三大流控策略
数字护盾:深度探讨Sentinel的三大流控策略
74 0
|
7月前
|
监控 测试技术 数据安全/隐私保护
如何集成Sentinel实现流控、降级、热点规则、授权规则总结
如何集成Sentinel实现流控、降级、热点规则、授权规则总结
275 0
|
7月前
|
Sentinel
一文速通Sentinel熔断及降级规则
一文速通Sentinel熔断及降级规则