0%

sentinel使用手册

Sentinel Dashboard 使用手册

Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard控制台。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果。

  • 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。

Sentinel 控制台包含如下功能:

  • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
  • **监控 (单机和集群聚合)**:通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
  • 规则管理和推送:统一管理推送规则。
  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

注意:Sentinel 控制台目前仅支持单机部署。Sentinel 控制台项目提供 Sentinel 功能全集示例,不作为开箱即用的生产环境控制台,若希望在生产环境使用请根据文档自行进行定制和改造。

控制台介绍

image.png

第①部分:

  • 实时监控:图形化界面显示接口(资源)的访问情况,主要是图表形式,图是线图,表内容有通过(拒绝QPS)响应时间等
  • 簇点链路:也就是上图信息,显示详细的资源以及调用链路信息,可以对相应的资源进行一系列的流控、熔断降级等操作,接下来会对这些信息进行说明和配置使用
  • 流控规则、熔断规则、热点规则、授权规则:和簇点链路里面资源的区别是需要手动添加资源名
  • 系统规则:对服务器资源的控制
  • 机器规则:对sentinel客户端集群配置的规则
  • 机器列表:机器的名称、IP地址、通信端口号、客户端版本号、健康状态、心跳时间等

目前Sentinel支持以下五种限流/熔断规则:

  • 基于资源限流(FlowRule)
  • 系统自适应限流(SystemRule)
  • 系统熔断降级(DegradeRule)
  • 热点参数限流(ParamFlowRule)
  • 基于授权的限流(AuthorityRule),其父类为AbstractRule
  • 网关限流,说到底就是Filter限流,控制限流资源范围。其实现原理为为Servlet添加了一个CommonFilter

第②部分:

流控规则

任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的,我们需要根据系统的处理能力对流量进行控制。

  Sentinel从以下两个方面的数量,对流量进行控制:

  1. QPS:每秒请求个数
  2. 线程数:并发线程个数

原理

监控应用流量的QPS(每秒查询个数) 或并发线程数等指标,当达到指定的阈值(规定的大小)时对流量进行控制。以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

详细解释

image.png

  • 资源名:可以简单的理解为接口名称,实际上可以是任何一段被保护起来的代码段,把这段被保护的代码起的一个资源名称,默认请求路径(如:http://localhost:8089/testA)
  • 针对来源:针对调用者进行限流,需要在对应微服务配置文件进行配置名称,然后填写在这里(和微服务名称没有关联),默认default(不区分来源,全部限制)
  • 阈值类型:QPS和并发线程数,对应的源码中FlowRule规则,单机阈值填写数值。当超过该值时,触发流控规则
  • 是否集群:是否为集群
  • 流控模式(限制谁):
    • 直接:只对当前资源名进行流控
    • 关联:对当前资源所关联的资源超过阈值的时候,会对当前资源进行流控
    • 链路:对入口资源设置的值进行流控
  • 流控效果(设置为QPS时可配):
    • 快速失败:直接响应失败,如浏览器访问接口时页面直接写出:Blocked by Sentinel (flow limiting)
    • Warm Up:预热模式,请求 QPS 从 阈值 / 3 开始,还会设置一个预热时长,在预热时间中逐渐升至设定的 QPS 阈值。也就是允许通过的请求数量由少逐渐变多,有一个缓冲的效果。
      • 这个时间端由预热时长进行配置(单位秒)(Warm Up选中就会在页面出现)
    • 排队等待:请求或者线程排队进行访问,默认是1秒内 单机阈值设置为10的时候,相当于100ms内有一个请求通过(当前场景不支持QPS大于1000的场景 )
      • 超时时间:单位毫秒,排队超时的请求会被拒绝,所以为了避免请求被拒绝,该值需要适当的配置大一点

熔断规则

熔断是一种保护机制,用于防止系统在高负载或异常情况下继续承受过大的流量压力,从而导致系统崩溃或性能下降。熔断规则可以根据系统的负载情况自动触发熔断,将流量限制在一个可控范围内。

在统计时长内的所有请求,如果请求时间超过xx秒(慢请求)的请求超过一定的比例,且请求数大于最小请求数,将触发熔断,效果是熔断时间内的请求会快速失败。

  经过熔断时间后,进入探测恢复状态,当下一个请求仍然是慢请求(请求时间超过xx秒),则再次进入熔断状态,不是则恢复正常状态。

流程图

image

详细解释

image.png

  • 资源名:受保护的资源的名称

  • 熔断策略:

    • 慢调用比例

      • 最大RT:设置最大响应时间。超过就算慢调用。RT是响应时间(reponse time)的意思,单位为毫秒。
      • 比例阈值:当时间窗口内统计的慢调用占总调用的比例超过该设置的值得时候,触发熔断机制。取值范围0.0-1.0,代表 0% - 100%。
    • 异常比例

      • 比例阈值:当时间窗口内统计的异常次数占总调用的比例超过该设置的值得时候,触发熔断机制

        在统计时长内的所有请求,如果异常的比例大于阈值,且请求数大于最小请求数,将触发熔断,效果是熔断时间内的请求会快速失败。

          经过熔断时间后,进入探测恢复状态,当下一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

    • 异常数

      • 异常数:当时间窗口内统计的异常次数超过该设置的值得时候,触发熔断机制

        和异常比例策略是相差不大,比较的是异常数是否超过设置。

  • 最小请求数:请求数小于该值时,即使异常比率超出阈值也不会熔断。默认是5。

  • 熔断时长:触发熔断时持续时长,(超过这个时间之后,处于半开状态。后续访问不触发熔断时,可以自己修复)

  • 统计时长:设置一个时间窗口用于统计。可以是每1分钟、每3小时。根据这个时间内的请求,来统计总请求和数、计算慢调用比例。

几种降级策略

我们通常用以下几种降级策略:

  • 平均响应时间 (DEGRADE_GRADE_RT):

    当资源的平均响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求(即 QPS >= 5),它们的 RT 都持续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。

    注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。

  • 异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):

    当资源的每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。

    异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

  • 异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):

    当资源近 1 分钟的异常数目超过阈值之后会进行熔断。

    注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

热点规则

原理

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

详细解释

image.png

  • 热点规则需要搭配@SentinelResource注解使用
  • 资源名:是使用@SentinelResource注解定义的名称
  • 参数索引:调用被保护的资源时传入的参数的索引位置,指定索引位置来指定热点参数;举个例子:当只有一个参数时,参数索引应该配置为0
  • 参数类型:参数对应的基本数据类型,否则配置无效
  • 参数值:根据该设置值,作为热点参数值进行保护 (如商品的唯一标识作为参数时)
  • 限流阈值:当QPS模式下,超过该设置的值得时候,会触发资源保护
  • 单机阈值:这个是当前接口资源(其他参数值时)超过了单机阈值,也会触发保护机制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@SentinelResource(value = "ResOrderGet",fallback = "fallback",fallbackClass = SentinelExceptionHandler.class,blockHandler = "blockHandler",blockHandlerClass = SentinelExceptionHandler.class)
@GetMapping("/order/get/{id}")
public Result<StockModel> getStockDetails(@PathVariable Integer id)
{
StockModel stockModel = new StockModel();
stockModel.setCode("STOCK==>1000");
stockModel.setId(id);
return Result.success(stockModel);
}
// 异常处理类
public class SentinelResourceExceptionHandler {
//限流熔断业务逻辑
public static Result<StockModel> blockHandler(@PathVariable Integer id) { return Result.error(null, -100, "系统错误 (限流熔断业务逻辑)");
}
//异常降级业务逻辑
public static Result<StockModel> fallback(@PathVariable Integer id) {
return Result.error(null, -100, "系统错误 (异常降级业务逻辑)");
}
}

系统规则

image.png

  • 阈值类型

    • LOAD:在Linux类型的服务器才能生效,使用的是服务器上的load1指标进行自适应触发系统保护
    • RT:入口处所有的接口响应时长的平均RT超过设置的阈值时,触发系统规则,阈值单位默认是ms
    • 线程数:单机上总的入口处的线程数超过阈值的时候,会触发系统规则保护
    • 入口QPS:单机上总的入口处QPS总数,当超过设定的阈值的时候,触发系统规则进行保护
    • CPU使用率:机器上的CPU使用率超过阈值时,就会触发系统规则,阈值设置范围是[0-1]
  • 阈值

    • 对应类型设置的数值,超过该值时,是会触发系统规则的

授权规则

原理

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

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

1
2
3
4
5
6
7
8
9
10
// 注意导包
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");
}
}

详细解释

image.png

  • 资源名:受保护的资源名称

  • 流控应用:调用方的名称

    • 需要在业务代码中使用filter或者interceptor中拦截判断 可以实现RequestOriginParser接口进行判断
    • 访问链接带上k=v v即是流控应用中配置的值
  • 授权类型:

    • 白名单:可以调用指定的资源名对应的资源

    • 黑名单:不可以调用指定的资源名对应的资源

监控

“簇点链路”中显示刚刚调用的资源(单机实时)

簇点链路(单机调用链路)页面实时的去拉取指定客户端资源的运行情况。它一共提供两种展示模式:一种用树状结构展示资源的调用链路,另外一种则不区分调用链路展示资源的运行情况。

注意: 簇点监控是内存态的信息,它仅展示启动后调用过的资源。

“实时监控”汇总资源信息(集群聚合)

同时,同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在”实时监控”下。

注意: 实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制。

dashboard-overview

注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。

规则管理及推送

规则管理

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

rules

规则推送

dashboard-add-rule

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

为了持久保存规则,建议使用下文中的“动态规则配置”

动态规则配置

Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:

  • 通过 API 直接修改 (loadRules)
  • 通过 DataSource 适配不同数据源修改

通过 API 直接修改

手动通过API定义规则,是一种硬编码的形式,因为不够灵活,所以肯定不能应用于生产环境。

举个列子:

1、定义规则

1
2
3
4
5
6
7
8
9
10
11
//定义了资源 `HelloWorld` 每秒最多只能通过 20 个请求。
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}

2、对应运行代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) throws Exception {
initFlowRules();
while (true) {
Entry entry = null;
try {
entry = SphU.entry("HelloWorld");
/*您的业务逻辑 - 开始*/
System.out.println("hello world");
/*您的业务逻辑 - 结束*/
} catch (BlockException e1) {
/*流控逻辑处理 - 开始*/
System.out.println("block!");
/*流控逻辑处理 - 结束*/
} finally {
if (entry != null) {
entry.exit();
}
}
}
}

nacos持久化配置

引入DataSource,规则设置可以存储在数据源中,通过更新数据源中存储的规则,推送到Sentinel规则中心,客户端就可以实时获取最新的规则,根据最新的规则进行限流、降级。

一般DataSource拓展常见的实现方式有:

  • 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是SQL、文件等。优点是比较简单,缺点是无法及时获取变更。
  • 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证,比较推荐使用这种方式。

pull模式(不推荐)

pull模式的数据源一般是可写入的(比如本地文件)。首先要在客户端注册数据源,将对应的读数据源注册至对应的 RuleManager;然后将写数据源注册至 transport 的 WritableDataSourceRegistry 中。

由此看出这是一个双向读写的过程,我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。下图为控制台推送规则的流程图。
在这里插入图片描述
首先引入maven依赖。

1
2
3
4
5
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<version>1.8.1</version>
</dependency>

使用SPI机制进行扩展,创建一个实现类,实现InitFunc接口的init()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class FileDataSourceInit implements InitFunc {

public FileDataSourceInit() {
}

@Override
public void init() throws Exception {
String filePath = System.getProperty("user.home") + "\\sentinel\\rules\\sentinel.json";
ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
filePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
})
);
// 将可读数据源注册至 FlowRuleManager.
FlowRuleManager.register2Property(ds.getProperty());

WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(filePath, this::encodeJson);
// 将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中.
// 这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中.
WritableDataSourceRegistry.registerFlowDataSource(wds);
}

private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}

在项目的 resources/META-INF/services 目录下创建文件,名为com.alibaba.csp.sentinel.init.InitFunc ,内容则是FileDataSourceInit的全限定名称:

1
io.github.yehongzhi.springmvc.config.FileDataSourceInit

接着在${home}目录下,创建\sentinel\rules目录,再创建sentinel.json文件。
在这里插入图片描述

此时当我们启动项目后,客户端会自动触发上述初始化操作。然后在操作台中进行流量限流规则等的设置,相关配置信息将同步保存到本地文件sentinel.json中(压缩成一行的json)。

push模式(推荐)

push模式将配置放在nacos上,与我们目前的设置方式一致。

客户端接入控制台

添加依赖

首先添加maven依赖,客户端需要引入 Transport 模块和自定义starter来与 Sentinel 控制台进行通信。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.jxcc</groupId>
<artifactId>jxcc-spring-boot-sentinel-starter</artifactId>
<version>0.1.3-SNAPSHOT</version>
</dependency>
</dependencies>

ncaos配置

该配置信息请严格遵守。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
sentinel:
transport:
dashboard: localhost:8080
eager: true #是否开启网关限流,默认true
web-context-unify: false # 默认将调用链路收敛,导致链路流控效果无效
datasource:
flow:
nacos:
server-addr: 10.99.186.131:8848
username: nacos
password: nacos
dataId: ${spring.application.name}-flow-rules
groupId: DEFAULT_GROUP
dataType: json
rule-type: flow
degrade:
nacos:
server-addr: 10.99.186.131:8848
username: nacos
password: nacos
dataId: ${spring.application.name}-degrade-rules
groupId: DEFAULT_GROUP
dataType: json
rule-type: degrade
system:
nacos:
server-addr: 10.99.186.131:8848
username: nacos
password: nacos
dataId: ${spring.application.name}-system-rules
groupId: DEFAULT_GROUP
dataType: json
rule-type: system
authority:
nacos:
server-addr: 10.99.186.131:8848
username: nacos
password: nacos
dataId: ${spring.application.name}-authority-rules
groupId: DEFAULT_GROUP
dataType: json
rule-type: authority
param-flow:
nacos:
server-addr: 10.99.186.131:8848
username: nacos
password: nacos
dataId: ${spring.application.name}-param-rules
groupId: DEFAULT_GROUP
dataType: json
rule-type: param-flow

json 参数详解

流控规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[
{
// 资源名
"resource": "/test",
// 针对来源,若为 default 则不区分调用来源
"limitApp": "default",
// 限流阈值类型(1:QPS;0:并发线程数)
"grade": 1,
// 阈值
"count": 1,
// 是否是集群模式
"clusterMode": false,
// 流控效果(0:快速失败;1:Warm Up(预热模式);2:排队等待)
"controlBehavior": 0,
// 流控模式(0:直接;1:关联;2:链路)
"strategy": 0,
// 预热时间(秒,预热模式需要此参数)
"warmUpPeriodSec": 10,
// 超时时间(排队等待模式需要此参数)
"maxQueueingTimeMs": 500,
// 关联资源、入口资源(关联、链路模式)
"refResource": "rrr"
}
]

降级规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[
{
// 资源名
"resource": "/test1",
"limitApp": "default",
// 熔断策略(0:慢调用比例,1:异常比率,2:异常计数)
"grade": 0,
// 最大RT、比例阈值、异常数
"count": 200,
// 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)
"slowRatioThreshold": 0.2,
// 最小请求数
"minRequestAmount": 5,
// 当单位统计时长(类中默认1000)
"statIntervalMs": 1000,
// 熔断时长
"timeWindow": 10
}
]

热点规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[
{
// 资源名
"resource": "/test1",
// 限流模式(QPS 模式,不可更改)
"grade": 1,
// 参数索引
"paramIdx": 0,
// 单机阈值
"count": 13,
// 统计窗口时长
"durationInSec": 6,
// 是否集群 默认false
"clusterMode": 默认false,
//
"burstCount": 0,
// 集群模式配置
"clusterConfig": {
//
"fallbackToLocalWhenFail": true,
//
"flowId": 2,
//
"sampleCount": 10,
//
"thresholdType": 0,
//
"windowIntervalMs": 1000
},
// 流控效果(支持快速失败和匀速排队模式)
"controlBehavior": 0,
//
"limitApp": "default",
//
"maxQueueingTimeMs": 0,
// 高级选项
"paramFlowItemList": [
{
// 参数类型
"classType": "int",
// 限流阈值
"count": 222,
// 参数值
"object": "2"
}
]
}
]

系统规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
// RT
"avgRt": 1,
// CPU 使用率
"highestCpuUsage": -1,
// LOAD
"highestSystemLoad": -1,
// 线程数
"maxThread": -1,
// 入口 QPS
"qps": -1
}
]

授权规则

1
2
3
4
5
6
7
8
9
10
[
{
// 资源名
"resource": "sentinel_spring_web_context",
// 流控应用
"limitApp": "/test",
// 授权类型(0代表白名单;1代表黑名单。)
"strategy": 0
}
]

参考文章

basic-api-resource-rule | Sentinel (sentinelguard.io)