Skip to content
第 59 章 后端 ⏱ 8 分钟阅读

第 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: true
java
@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

动手练习 ​

  1. 配一个 QPS=10 的限流,JMeter 压到 100 看效果
  2. 模拟下游挂掉,看熔断是否生效

下一章:第 60 章:定时任务(Xxl-Job + Spring Schedule) →

本站基于 VitePress 构建 · 由 StackHub 团队维护