第 59 章:Sentinel 限流与熔断
学习目标
- 集成 Sentinel
- 学会流量控制
- 学会熔断降级
一、Sentinel 干啥
Sentinel = 流量控制 + 熔断降级 + 系统保护。
| 概念 | 含义 |
|---|---|
| 限流 | 太多请求拒绝一部分 |
| 熔断 | 下游挂了,直接返回默认值 |
| 降级 | 非核心功能主动关闭 |
| 系统保护 | CPU 高时拒绝所有请求 |
二、集成
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>yaml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台
eager: true启动 Sentinel 控制台(docker):
bash
docker run -d --name sentinel -p 8080:8080 \
bladex/sentinel-dashboard:latest访问 http://localhost:8080,默认账号 sentinel / sentinel。
三、限流规则
代码配置:
java
@PostConstruct
public void initRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("createOrder"); // 资源名
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按 QPS
rule.setCount(10); // 每秒 10 个
rules.add(rule);
FlowRuleManager.loadRules(rules);
}注解配置(推荐):
java
@SentinelResource(value = "createOrder", blockHandler = "handleBlock")
@PostMapping("/orders")
public Result<Order> create(@RequestBody OrderDTO dto) {
return Result.ok(orderService.create(dto));
}
public Result<Order> handleBlock(OrderDTO dto, BlockException e) {
log.warn("限流: {}", e.getMessage());
return Result.error(429, "系统繁忙,请稍后再试");
}⚠️ 坑 1:
blockHandler方法必须和原方法同参数,只是最后加BlockException。
四、限流模式
| 模式 | 说明 |
|---|---|
| 直接 | 超过阈值直接拒绝 |
| 关联 | A 资源触发限流时,B 也被限流 |
| 链路 | 入口资源的限流 |
java
FlowRule rule = new FlowRule("createOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(10);
rule.setStrategy(RuleConstant.STRATEGY_DIRECT); // 直接五、熔断降级
java
@SentinelResource(value = "queryUser", fallback = "queryFallback")
public User queryUser(Long id) {
return userService.getById(id); // 调远程服务
}
public User queryFallback(Long id, Throwable e) {
log.warn("降级: {}", e.getMessage());
return new User(); // 返回默认值
}三种熔断策略:
| 策略 | 触发条件 |
|---|---|
| 慢调用比例 | 慢调用数 / 总调用数 > 阈值 |
| 异常比例 | 异常数 / 总数 > 阈值 |
| 异常数 | 异常数 > 阈值 |
控制台配置:
yaml
spring:
cloud:
sentinel:
rules:
- resource: queryUser
grade: DEGRADE_GRADE_EXCEPTION_RATIO
count: 0.5 # 50% 异常触发熔断
timeWindow: 10 # 熔断 10s
minRequestAmount: 10 # 最小请求数六、热点参数限流
java
@SentinelResource("hotParam")
@GetMapping("/products/{id}")
public Product getById(@PathVariable Long id) {
return productService.getById(id);
}控制台配置热点参数:对 id=1 限流 100 QPS,其它 1 QPS。
防止热点商品被刷爆。
七、与 OpenFeign 整合
yaml
spring:
cloud:
openfeign:
sentinel:
enabled: truejava
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/users/{id}")
User getById(@PathVariable Long id);
}
@Component
public class UserClientFallback implements UserClient {
@Override
public User getById(Long id) {
return new User();
}
}远程服务挂了,自动调用 fallback。
八、本章小结
| 要点 | 关键 |
|---|---|
| 限流 | @SentinelResource + 控制台 |
| 熔断 | fallback + 熔断规则 |
| 热点 | 热点参数限流 |
| OpenFeign | 集成 Sentinel |
动手练习
- 配一个 QPS=10 的限流,JMeter 压到 100 看效果
- 模拟下游挂掉,看熔断是否生效