Appearance
Sentinel简介
Alibaba Sentinel 是阿里巴巴开源的面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
下载与安装
下载地址:https://github.com/alibaba/Sentinel/releases
基于 Spring Boot 开发,下载jar包可以直接运行
启动命令示例:java -jar sentinel-dashboard-1.7.0.jar
访问sentinel管理界面:http://localhost:8080/
sentinel管理界面默认端口8080,默认账号密码都是sentinel
注意:sentinel-dashboard 的流控规则是懒加载的,即只有当有请求过来时,才会加载对应的流控规则。
如何连接sentinel
引入依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>主启动类相关注解
java
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现功能,确保 Sentinel 能够与服务注册中心(如 Nacos)进行交互。
@EnableSentinel // 启用 Sentinel 的自动配置,确保 Sentinel 的功能能够正常启动。
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}yaml配置
yaml
spring:
application:
name: your-service-name # 填写你的微服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos注册中心地址
sentinel:
transport:
dashboard: localhost:8080 # 配置 Sentinel dashboard 地址
port: 8719 # 微服务与Sentinel控制台的通信端口,默认8719,假如占用会自动从8719开始递增扫描可用端口流控规则
Sentinel的流控规则(流量控制规则)的核心作用是保护系统不被过量请求拖垮,确保服务在高并发下的稳定性和可用性。它就像一个智能的“流量阀门”或“交警系统”,在系统流量过大时进行控制,防止系统因过载而崩溃。
| 类别 | 策略 | 核心思想 | 典型应用场景 |
|---|---|---|---|
| 流控模式 | 直接 | 资源本身达到阈值,直接限流自身 | 通用接口保护,精确知道接口容量 |
| 关联 | 关联资源达到阈值,限流本资源("别人惹事,自己买单") | 数据库读写争抢,订单与支付,优先级不同的操作 | |
| 链路 | 根据调用入口限流,粒度更细 | 限制特定入口对公共服务的访问 | |
| 流控效果 | 快速失败 | QPS超限,立即抛异常 | 系统处理能力确切已知 |
| Warm Up | 流量缓慢增加至阈值,给系统预热时间 | 秒杀系统、冷系统启动 | |
| 排队等待 | 请求匀速通过,利用间隔时间处理 | 消息队列、脉冲流量(削峰填谷) |
降级规则
Sentinel的降级规则(也称为熔断降级规则)的核心作用是当系统出现不稳定因素时,主动切断不稳定的服务调用,防止故障蔓延,保证核心业务的可用性。根据设置的熔断时长,当熔断触发时,会进行自我恢复,恢复时间段内,请求会自动通过,直到熔断再次触发。
降级规则 - RT(秒级平均响应时间)
- 触发机制:当单位统计时间内慢调用请求数占总请求数的比例超过阈值时触发。
- 应用场景:依赖的数据库查询或第三方接口响应变慢。防止慢调用累积耗尽系统线程资源。
降级规则 - 异常比例
- 触发机制:当单位统计时间内异常请求数占总通过量(即成功处理的请求) 的比例超过阈值时触发。
- 应用场景:下游服务不稳定,抛出业务异常增多(如参数校验失败、空指针等)。服务调用超时或网络波动导致的失败。
降级规则 - 异常数
- 触发机制:当单位统计时间内请求的异常总数超过阈值时触发。
- 应用场景:依赖服务完全不可用(如网络断开、服务未启动)。需要快速阻断对严重故障服务的调用。
热点限流规则
Sentinel热点规则(Hotspot Parameter Flow Control)的核心作用是对请求中的特定参数进行精细化的流量控制,防止因热点数据(如热门商品、频繁操作的用户等)导致系统过载。
热点限流规则 - 参数索引限流
- 控制维度:基于方法参数的位置
- 适用场景:通用参数限流,如用户ID、商品ID等
- 配置特点:按参数位置(第0、1、2...个参数)配置
热点限流规则 - 参数索引限流
- 控制维度:基于参数的具体值
- 适用场景:特定热点数据,如热门商品、频繁操作的用户
- 配置特点:对特定参数值设置不同的阈值(例如接口中心,不同的商家id限流策略不同)
热点限流规则 - 参数索引限流
- 控制维度:基于多个参数的组合
- 适用场景:复杂的业务场景,需要多维度识别热点
- 配置特点:配置多个参数索引的组合规则
系统规则
Sentinel系统规则是从系统整体维度进行流量控制,保护整个系统的稳定性。它不针对某个具体接口或资源,而是关注系统的整体健康指标,防止系统因整体负载过高而崩溃。
LOAD(系统负载)
- 触发条件:当系统最近1分钟的负载(例如Unix系统的load1)超过阈值时触发保护。该规则仅对Unix/Linux系统有效,并且需要引入oshi-core依赖来获取系统负载。
- 适用场景:适用于物理机或虚拟机,需要监控系统的负载情况。当系统负载过高时,说明系统资源已经非常紧张,此时应限制流量,防止系统崩溃。
RT(平均响应时间)
- 触发条件:当系统所有入口资源的平均响应时间达到阈值(单位:毫秒)时触发保护。需要设置一个时间窗口,在该窗口内统计平均响应时间。
- 适用场景:当系统整体响应时间变长,说明系统处理能力下降,可能由于资源不足或内部服务缓慢。此时限流可以避免系统进一步恶化。
线程数
- 触发条件:当系统所有入口资源的并发线程数达到阈值时触发保护。此规则针对的是所有入口资源的线程数总和。
- 适用场景:当系统同时处理的请求线程数过多,会导致线程池耗尽,可能引起系统雪崩。通过限制总线程数,可以防止线程资源被耗尽。
QPS(每秒查询率)
- 触发条件:当系统所有入口资源的QPS总和达到阈值时触发保护。
- 适用场景:防止系统总请求量过大,超过系统处理能力。适用于对系统总流量进行限制,确保系统在安全容量内运行。
CPU使用率
- 触发条件:当系统CPU使用率超过阈值(0-100%)时触发保护。需要引入oshi-core依赖来获取CPU使用率。
- 适用场景:当CPU使用率过高时,系统响应能力会下降。通过限制流量,可以降低CPU负载,保证系统稳定。
核心注解@SentinelResource
@SentinelResource注解的核心功能是定义资源,并为其配置限流/熔断后的处理逻辑 和业务异常后的降级逻辑。
| 注解属性 ⚙️ | 说明 📖 | 注意 📌 |
|---|---|---|
| value | 资源名,规则作用的目标。 | 必填,规则据此定位。 |
| blockHandler | 流控/熔断处理方法名。触发流控规则(FlowRule)或降级规则(DegradeRule)时的处理逻辑。 | 参数需在原方法基础上加最后的 BlockException。 |
| blockHandlerClass | 指定存放blockHandler的类。 | 对应方法须是 static 的。 |
| fallback | 业务异常处理方法名。当方法抛出非BlockException 的其他异常时,提供降级逻辑。 | 参数可与原方法一致,或在最后加 Throwable。 |
| fallbackClass | 指定存放fallback的类。 | 对应方法须是 static 的。 |
| defaultFallback | 默认的通用降级方法名。 | 自 1.6.0 版本支持。 |
| exceptionsToIgnore | 排除特定的异常类型,这些异常将不触发 fallback 逻辑。 | 自 1.6.0 版本支持。 |
以下是一个包含流控处理和安全降级的常见示例:
java
@Service
public class SomeService {
// 定义资源,并指定流控处理方法和业务降级方法
@SentinelResource(value = "hello",
blockHandler = "handleBlock",
fallback = "handleFallback")
public String hello(String name) {
// 模拟业务逻辑,这里可能会抛出各种业务异常
if (name == null) {
throw new IllegalArgumentException("name cannot be null");
}
return "Hello, " + name;
}
// 流控或熔断处理函数 (BlockException 处理)
// 参数列表需与原方法匹配,并在最后添加 BlockException 参数
public String handleBlock(String name, BlockException ex) {
// 记录日志或执行其他流控处理逻辑
System.err.println("触发流控或熔断: " + ex.getClass().getSimpleName());
return "系统繁忙,请稍后重试";
}
// 业务异常降级函数 (通用异常处理)
// 参数列表可与原方法一致,或在最后添加 Throwable 参数来接收异常
public String handleFallback(String name, Throwable t) {
// 处理业务异常,提供降级结果
System.err.println("业务执行异常,执行降级逻辑: " + t.getMessage());
return "服务暂时不可用";
}
}与OpenFeign结合使用,@FeignClient注解里可以加入fallback=XxxFallback.class,XxxFallback类实现Feign接口并定义fallback方法来处理异常兜底,实现客户端提前降级熔断(防止服务端挂掉拖垮客户端)
集群的流控管理(Token Server)
- 在Sentinel控制台中,"是否集群"这个选项,决定了限流规则的作用范围。(不勾选时仅对当前单个服务实例生效,勾选则对整个服务集群的总流量进行限制)
- 由于默认情况下仅考虑单机限流,因此计算行为在客户端中进行,当需要考虑集群流控时,需要一个Token Server来统一管理流控规则。
- Token Server 为保证集群流控规则一致且不丢失,必须配置动态规则数据源(如Nacos)。防止Token Server重启后规则丢失。
- 如果Token Server宕机,集群流控会失效并退化到单机限流模式。
使用方法:下载启动Token Server后修改客户端配置,添加Token Server的连接配置
yaml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
port: 8719
cluster:
client:
server-ip: 192.168.1.100 # Token Server的IP地址
server-port: 11111 # Token Server的端口
request-timeout-ms: 200000 # 请求超时时间Token Server集群
实际上,Sentinel的Token Server集群高可用方案并没有官方正式发布,因为在Sentinel的集群流控设计中,Token Server本身并不是无状态的,它维护了全局的计数。如果某个Token Server宕机,那么它维护的计数状态就会丢失,而且客户端连接断开后需要重新连接到另一个Token Server,这期间可能会造成流控数据的不一致。
社区和实践中的一些思路:使用多个Token Server,客户端配置多个地址:在客户端配置中,可以指定多个Token Server的地址。客户端会按顺序尝试连接,直到连接成功。这样,当其中一个Token Server宕机时,客户端可以自动切换到另一个。但是,这种方式有一个问题:多个Token Server之间状态如何同步?Sentinel默认没有提供状态同步机制。
另一种思路:不做Token Server集群,而是部署多个Token Server,每个Token Server都负责一个业务线,既保证单独的Token Server宕机不影响其他业务线,同时也可以将单独的Token Server放在相关业务的内网里来保证网络稳定和低延迟。
持久化
说明:通过Nacos实现Sentinel规则持久化,主要目的是解决默认内存存储规则时,应用重启规则会消失的问题。这确保了生产环境中规则配置的稳定性。
在项目的 pom.xml 中引入Sentinel数据源Nacos依赖:
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.6</version> <!-- 建议使用最新稳定版本 -->
</dependency>配置数据源,在 application.yml 中配置Sentinel数据源指向Nacos:
yaml
spring:
application:
name: your-service-name # 你的微服务名称
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
port: 8719
datasource:
# 数据源名称,可自定义
flow-rule: # 流控规则
nacos:
server-addr: localhost:8848 # Nacos服务器地址
dataId: ${spring.application.name}-flow-rules # 在Nacos中对应的Data ID
groupId: DEFAULT_GROUP # 分组,默认为DEFAULT_GROUP
data-type: json # 数据类型
rule-type: flow # 规则类型,此处为流控规则
degrade-rule: # 降级规则(可选)
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade # 除了流控规则(flow),还可配置降级规则(degrade)、系统规则(system)等,只需在datasource下新增数据源并设置对应的rule-type。在Nacos配置中心创建对应的Data ID(例如 your-service-name-flow-rules),配置内容为JSON数组格式的流控规则:
注意:在Sentinel控制台界面添加的规则是无法自动持久化到Nacos的。在Dashboard上操作的流控规则,默认是通过Sentinel客户端提供的API直接发送到您微服务应用的内存中。这意味着规则并未被写入Nacos,因此应用一旦重启,这些内存中的规则就会丢失。
json
[
{
"resource": "/api/query",
"limitApp": "default",
"grade": 1,
"count": 10,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]控制台集群(官方默认单机部署)
- 官方明确指出,Sentinel控制台目前更侧重于功能展示,默认设计是用于单机部署,若要在生产环境中高可用地使用,通常需要我们自己进行一些改造和配置。
- 在实际应用场景中,大多数项目确实不需要搭建Sentinel控制台集群,单机部署已经能够满足需求。
- Sentinel控制台主要是管理和监控界面,不参与核心的流量控制决策
- 规则配置通过控制台下发,但实际限流逻辑在客户端执行
- 控制台宕机不会影响已有的流控规则执行,只会影响规则修改和监控查看
- 日常使用中,控制台主要是偶尔查看监控、调整规则,并非高频访问