Sentinel 限流熔断
什么是 Sentinel?
Sentinel 是阿里巴巴开源的流量控制组件,提供:
- 流量控制:限制 QPS
- 熔断降级:服务不可用时快速失败
- 系统保护:保护系统不被压垮
核心概念
| 概念 | 说明 |
|---|---|
| 资源 | 被保护的对象(API 接口、方法) |
| 规则 | 限流/熔断/系统保护规则 |
| Entry | 资源访问入口 |
| Context | 调用链上下文 |
快速开始
依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台
eager: true # 立即初始化代码使用
@Service
public class UserService {
@SentinelResource(value = "getUser", blockHandler = "handleBlock")
public User getUser(Long id) {
return userDao.findById(id);
}
// 限流/熔断时的处理方法
public User handleBlock(Long id, BlockException ex) {
return new User(-1L, "服务繁忙,请稍后重试");
}
}流量控制
QPS 限流
// 代码方式
FlowRule rule = new FlowRule();
rule.setResource("getUser");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(10); // 每秒最多 10 次
FlowRuleManager.loadRules(Collections.singletonList(rule));控制台配置
资源名:getUser
阈值类型:QPS
单机阈值:10流控模式
| 模式 | 说明 |
|---|---|
| 直接 | 默认,直接限流 |
| 关联 | 关联资源达到阈值时限流 |
| 链路 | 指定入口限流 |
流控效果
| 效果 | 说明 |
|---|---|
| 快速失败 | 直接抛异常 |
| Warm Up | 预热,缓慢增加阈值 |
| 排队等待 | 排队,超时失败 |
熔断降级
熔断策略
| 策略 | 说明 |
|---|---|
| 慢调用比例 | 响应时间超过阈值 |
| 异常比例 | 异常比例超过阈值 |
| 异常数 | 异常数超过阈值 |
慢调用比例
DegradeRule rule = new DegradeRule();
rule.setResource("getUser");
rule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());
rule.setCount(100); // 慢调用阈值:100ms
rule.setSlowRatioThreshold(0.5); // 慢调用比例:50%
rule.setMinRequestAmount(10); // 最小请求数
rule.setStatIntervalMs(10000); // 统计时长
rule.setTimeWindow(10); // 熔断时长:10秒
DegradeRuleManager.loadRules(Collections.singletonList(rule));异常比例
DegradeRule rule = new DegradeRule();
rule.setResource("getUser");
rule.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
rule.setCount(0.5); // 异常比例:50%
rule.setMinRequestAmount(10);
rule.setStatIntervalMs(10000);
rule.setTimeWindow(10);注解方式
@SentinelResource(value = "getUser",
blockHandler = "handleBlock",
fallback = "handleFallback")
public User getUser(Long id) {
if (id < 0) {
throw new IllegalArgumentException("id 不能为负");
}
return userDao.findById(id);
}
// 限流/熔断处理
public User handleBlock(Long id, BlockException ex) {
return new User(-1L, "服务繁忙");
}
// 业务异常处理
public User handleFallback(Long id, Throwable ex) {
return new User(-1L, "参数错误");
}热点参数限流
@SentinelResource(value = "getUser", blockHandler = "handleBlock")
public User getUser(@PathVariable Long id) {
return userDao.findById(id);
}
// 配置热点规则
ParamFlowRule rule = new ParamFlowRule();
rule.setResource("getUser");
rule.setCount(5); // 每秒最多 5 次
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setParamIdx(0); // 第一个参数
// 特定参数例外
ParamFlowItem item = new ParamFlowItem();
item.setObject("1"); // id=1 时
item.setCount(100); // 每秒 100 次
rule.setParamFlowItemList(Collections.singletonList(item));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));系统保护
SystemRule rule = new SystemRule();
rule.setQps(1000); // 系统 QPS 阈值
rule.setCpuUsage(0.8); // CPU 使用率阈值
rule.setAvgRt(100); // 平均响应时间阈值
rule.setMaxThread(100); // 最大并发线程数
SystemRuleManager.loadRules(Collections.singletonList(rule));整合 OpenFeign
feign:
sentinel:
enabled: true@FeignClient(value = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
}
@Component
public class UserClientFallback implements UserClient {
@Override
public User getUser(Long id) {
return new User(-1L, "服务不可用");
}
}面试高频问题
Q1: 限流和熔断的区别?
| 对比 | 限流 | 熔断 |
|---|---|---|
| 目的 | 防止流量过大 | 防止故障蔓延 |
| 触发条件 | QPS 超阈值 | 错误率/响应时间超阈值 |
| 状态 | 正常 | 开启/半开/关闭 |
Q2: 熔断器的三种状态?
关闭(Closed)→ 正常状态,请求正常通过
↓ 错误率超阈值
开启(Open)→ 熔断状态,快速失败
↓ 超时后
半开(Half-Open)→ 尝试恢复,放行部分请求
↓ 成功 → 关闭
↓ 失败 → 开启Q3: Sentinel 和 Hystrix 的区别?
| 对比 | Sentinel | Hystrix |
|---|---|---|
| 隔离策略 | 信号量 | 线程池/信号量 |
| 熔断策略 | 慢调用/异常比例/异常数 | 异常比例 |
| 实时监控 | 控制台 | 需要 Dashboard |
| 动态配置 | 支持 | 支持 |
| 状态 | 活跃 | 停止维护 |
总结
Sentinel 核心要点:
1. 流量控制:QPS 限流、热点参数限流
2. 熔断降级:慢调用比例、异常比例、异常数
3. 系统保护:CPU、QPS、RT、线程数
4. 注解:@SentinelResource
5. 整合:OpenFeign、Dubbo、Spring Cloud Gateway