第 226 章:Sentinel 熔断与限流
学习目标
- 理解熔断与降级
- 掌握 Sentinel 限流规则
- 集成 Sentinel Dashboard
- 实现系统自适应保护
一、Sentinel 简介
Sentinel 是阿里开源的流量治理组件,提供限流、熔断降级、系统自适应保护、热点参数限流四大能力。
1.1 与 Hystrix 对比
| 维度 | Sentinel | Hystrix |
|---|---|---|
| 限流 | ✅ 多维度 | ❌ 无 |
| 熔断 | ✅ 多种策略 | ✅ 滑动窗口 |
| 系统保护 | ✅ 自适应 | ❌ 无 |
| 热点参数 | ✅ | ❌ |
| 控制台 | ✅ 完善 | ⚠️ 弱 |
| 维护 | 活跃 | ⚠️ 停维 |
1.2 核心概念
| 概念 | 说明 |
|---|---|
| 资源(Resource) | 被保护的对象(API/方法) |
| 规则(Rule) | 限流/熔断规则 |
| 插槽(Slot) | 处理链上的功能点 |
| 上下文(Context) | 调用链入口 |
二、快速开始
2.1 引入依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>2.2 启动 Dashboard
bash
docker run -d --name sentinel-dashboard -p 8080:8080 \
-e AUTH_USERNAME=sentinel \
-e AUTH_PASSWORD=sentinel \
bladex/sentinel-dashboard:1.8.6访问: http://localhost:8080 (sentinel / sentinel)
2.3 客户端配置
yaml
spring:
application:
name: order-service
cloud:
sentinel:
transport:
dashboard: localhost:8080
eager: true # 启动时主动连接2.4 第一个资源保护
java
@Service
public class OrderService {
@SentinelResource(value = "createOrder", blockHandler = "createOrderBlockHandler")
public Order createOrder(OrderRequest req) {
return orderRepo.save(new Order(req));
}
// blockHandler 当限流/熔断时调用
public Order createOrderBlockHandler(OrderRequest req, BlockException ex) {
log.warn("触发限流: {}", ex.getMessage());
throw new BizException("系统繁忙,请稍后再试");
}
}三、限流规则
3.1 限流维度
| 维度 | 说明 |
|---|---|
| QPS | 每秒请求数 |
| 并发线程数 | 同时占用的线程数 |
| 资源 | 方法/URL |
| 来源 | 调用方(如只针对客户端 A) |
3.2 限流效果
| 类型 | 说明 |
|---|---|
| 快速失败 | 直接抛异常 |
| Warm Up | 预热(冷启动系统保护) |
| 排队等待 | 匀速通过 |
3.3 编程式定义规则
java
@Configuration
public class SentinelConfig {
@PostConstruct
public void initRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("createOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(10); // 10 QPS
rule.setLimitApp("default"); // 来源
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}3.4 通过 Dashboard 配置
更简单的方式,通过控制台动态生效。
Dashboard 配置示例:
资源名: /api/orders
阈值类型: QPS
阈值: 100
流控模式: 直接
流控效果: 快速失败3.5 关联模式
yaml
# A 接口触发限流后,B 接口也限流
resources: [A, B]
关联资源: B # A 限流时 B 跟着限流用途:写接口限流后,读接口也限流,保护整体。
3.6 链路模式
只针对指定入口的链路生效(流控效果)。
java
@SentinelResource(value = "getStock")
public InventoryDTO getStock(String skuId) { ... }
CtxUtil.enter("order-flow");
getStock("SKU-001"); // 此调用受流控
CtxUtil.exit();四、熔断降级
4.1 熔断策略
| 策略 | 触发条件 | 恢复 |
|---|---|---|
| 慢调用比例 | 响应时间 > 阈值且比例超阈值 | 探测 |
| 异常比例 | 异常 / 总数 > 阈值 | 探测 |
| 异常数 | 一分钟内异常数 > 阈值 | 探测 |
4.2 配置熔断
java
@PostConstruct
public void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule("queryOrder");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT); // 按异常数
rule.setCount(5); // 5 个异常
rule.setTimeWindow(10); // 10 秒熔断窗口
rule.setStatIntervalMs(60000); // 统计周期 60 秒
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}4.3 OpenFeign 集成 Sentinel
yaml
feign:
sentinel:
enabled: truejava
@FeignClient(
name = "inventory-service",
fallback = InventoryFallback.class,
fallbackFactory = InventoryFallbackFactory.class
)
public interface InventoryClient { ... }4.4 Fallback
java
@Component
public class InventoryFallback implements InventoryClient {
@Override
public Result<InventoryDTO> getStock(String skuId) {
return Result.busy();
}
}4.5 FallbackFactory(带异常)
java
@Component
public class InventoryFallbackFactory implements FallbackFactory<InventoryClient> {
@Override
public InventoryClient create(Throwable cause) {
return new InventoryClient() {
@Override
public Result<InventoryDTO> getStock(String skuId) {
if (cause instanceof FlowException) {
return Result.busy();
} else if (cause instanceof DegradeException) {
return Result.degraded();
} else {
return Result.error("服务异常: " + cause.getMessage());
}
}
};
}
}五、热点参数限流
针对特定参数值限流。
java
@SentinelResource(value = "getStock", blockHandler = "blockHandler")
public InventoryDTO getStock(@SentinelParam("skuId") String skuId) {
return inventoryService.get(skuId);
}控制台配置:
资源: getStock
参数索引: 0(第一个参数,即 skuId)
阈值:
SKU-001: 1000 QPS
SKU-002: 100 QPS
其他: 10 QPS应用:秒杀场景,热门商品单独限流。
六、系统自适应保护
Load 维度,系统级自我保护。
java
@PostConstruct
public void initSystemRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(4.0); // load1 < 4
rule.setMaxThread(800); // 总线程 < 800
rule.setQps(300); // QPS < 300
rule.setAvgRt(500); // 平均 RT < 500ms
rule.setHighestCpuUsage(0.8); // CPU < 80%
rules.add(rule);
SystemRuleManager.loadRules(rules);
}原理:入口流量一旦触达阈值,自动拒绝。
七、规则持久化
7.1 默认 Dashboard 规则丢失
Dashboard 重启后规则消失 → 需要持久化。
7.2 Nacos 模式(推荐)
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>yaml
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
data-id: order-service-sentinel
group-id: DEFAULT_GROUP
rule-type: flow # flow / degrade / param-flow / system7.3 Nacos 中的规则
json
[
{
"resource": "createOrder",
"grade": 1,
"count": 10,
"limitApp": "default"
}
]八、注解方式
8.1 @SentinelResource 详解
java
@SentinelResource(
value = "getOrder", // 资源名
blockHandler = "blockHandler", // 限流/降级回调
blockHandlerClass = BlockHandlerClass.class,
fallback = "fallback", // 业务异常回调
fallbackClass = FallbackClass.class,
exceptionsToIgnore = {IllegalArgumentException.class}
)
public Order getOrder(Long id) {
return orderService.get(id);
}8.2 异常区分
- BlockException(限流 / 熔断触发)→ blockHandler
- 业务异常(代码 throw 的)→ fallback
九、与 API 网关整合
9.1 Spring Cloud Gateway 集成
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>yaml
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
filters:
- name: SentinelGatewayFilterDashboard 中可针对路由配置网关级流控。
9.2 网关限流维度
- API 维度(按 URL)
- 用户维度(按 token / user-id)
- IP 维度
- 来源应用
十、生产案例
10.1 秒杀场景
java
@Service
public class SeckillService {
@SentinelResource(
value = "seckill",
blockHandler = "seckillBlock"
)
public String seckill(String skuId, String userId) {
return redisTemplate.opsForValue()
.decrement("seckill:stock:" + skuId) > 0
? "success"
: "sold out";
}
public String seckillBlock(String skuId, String userId, BlockException ex) {
return "系统繁忙,请稍后再试";
}
}限流规则:Sentinel Dashboard 配置 1000 QPS。
10.2 慢服务保护
java
@PostConstruct
public void initDegrade() {
DegradeRule rule = new DegradeRule("pay");
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); // 慢调用
rule.setCount(2000); // 2 秒
rule.setSlowRatioThreshold(0.5); // 一半超时
rule.setMinRequestAmount(10); // 至少 10 个请求
rule.setTimeWindow(30); // 30 秒熔断
DegradeRuleManager.loadRules(List.of(rule));
}十一、监控与告警
11.1 暴露指标
yaml
management:
endpoints:
web:
exposure:
include: '*'
metrics:
tags:
application: ${spring.application.name}11.2 Prometheus 抓取
sentinel_block_total{...}
sentinel_pass_total{...}
sentinel_reject_total{...}
sentinel_business_exception_total{...}
sentinel_context_interrupt_total{...}11.3 告警规则(Dashboard 配置)
Dashboard 支持 机器列表 → 配置监控,规则触发后通过 webhook 推送告警。
十二、与 Resilience4j 对比
| 维度 | Sentinel | Resilience4j |
|---|---|---|
| 语言 | Java | Java |
| 限流 | ✅ | ✅ |
| 熔断 | ✅ | ✅ |
| 集成 | Spring Cloud Alibaba | Spring Cloud 通用 |
| Dashboard | 完善 | 弱 |
| 规则配置 | 动态 | 多用配置文件 |
| 学习曲线 | 低 | 中 |
十三、本章小结
| 概念 | 作用 |
|---|---|
| @SentinelResource | 标记保护资源 |
| FlowRule | 限流规则 |
| DegradeRule | 熔断规则 |
| ParamFlowRule | 热点参数限流 |
| SystemRule | 系统自适应 |
| BlockHandler | 限流回调 |
| Fallback | 异常降级 |
动手练习
- 配置 Sentinel Dashboard,在应用启动后注册成功
- 用
@SentinelResource保护下单接口,触发 QPS 限流 - 配置熔断规则,故意制造异常触发熔断
- 用 Nacos 持久化 Sentinel 规则
- 网关层配置 Sentinel 全局限流(1000 QPS)
推荐阅读
下一章:第 227 章:分布式事务