流量整形与熔断:Sentinel 流控实战

FreeGuideOnline 最新 2026-06-30

xml com.alibaba.cloud spring-cloud-starter-alibaba-sentinel 2021.0.5.0


### 3. 配置控制台
Sentinel 提供一个轻量级控制台用于规则管理和监控。下载 [sentinel-dashboard.jar](https://github.com/alibaba/Sentinel/releases) ,启动命令:

```bash
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar

在 Spring Boot 的 application.yml 中配置控制台地址:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080   # 控制台地址
        port: 8719                  # 本地通信端口,选一个未被占用的

启动你的应用并访问 http://localhost:8080 ,默认账号密码均为 sentinel,即可看到控制台。


流量控制:实现精准限流

流控规则概览

Sentinel 通过对资源的调用进行限制来保护服务。资源可以是 URL、方法等。流控规则主要包含以下属性:

  • 资源名:唯一标识,如 /order/create
  • 限流阈值类型:QPS(每秒请求数)或并发线程数。
  • 流控模式:直接、关联、链路。
  • 流控效果:快速失败、Warm Up(预热)、匀速排队。

实战:基于 QPS 的直接限流

创建一个简单的 REST 接口:

@RestController
public class DemoController {
    @GetMapping("/hello")
    @SentinelResource(value = "hello", blockHandler = "helloBlockHandler")
    public String hello() {
        return "Hello Sentinel!";
    }

    // 限流后的降级处理逻辑
    public String helloBlockHandler(BlockException ex) {
        return "系统繁忙,请稍后再试";
    }
}

访问一次 /hello 后,在控制台左侧出现名为 hello 的资源。点 “流控规则” → “新增流控规则”,设置:

  • 阈值类型:QPS
  • QPS 阈值:2
  • 流控模式:直接
  • 流控效果:快速失败

保存后,用工具(如 JMeter 或 curl)在 1 秒内连续请求 3 次,会看到第 3 次及后续请求返回 “系统繁忙,请稍后再试”。

流量整形效果详解

1. 快速失败(直接拒绝)

这是最直接的方式,当 QPS 超过阈值时,新请求立刻被拒绝,抛出 FlowException。适用于对突发流量零容忍的场景,如秒杀下单。

2. Warm Up(预热)

系统长期处于低水位时,突然涌入大量流量可能瞬间压垮系统(例如缓存未预热)。Warm Up 让通过的 QPS 缓慢增加,经过一段预热时间后才到达设定的阈值。

配置示例

  • 阈值:100
  • 流控效果:Warm Up
  • 预热时长:10 秒

效果:最初允许通过的 QPS 为 100/3 ≈ 33,然后在 10 秒内线性增长至 100。这为系统留出预热时间。

3. 匀速排队(排队等待)

请求以均匀的速度通过,多余请求排队等待,若等待超时则拒绝。它使流量曲线变得平滑,类似漏桶算法。

配置示例

  • 阈值:QPS 为 5
  • 流控效果:匀速排队
  • 超时时间:500 毫秒

效果:每秒严格通过 5 个请求,后续请求进入队列,如果等待超过 500ms 则拒绝。这种方式适合处理突发流量后需要“削峰填谷”的场景,如消息处理。

关联与链路流控模式

  • 关联模式:当关联资源达到阈值时,限流当前资源。比如支付接口 /pay 关联到下单接口 /order,当 /order 的 QPS 过高时,限制 /pay 的访问,优先保证核心下单链路。
  • 链路模式:针对一条调用链路上的入口限流。例如 getUserInfo 方法被多个接口调用,只想限制来自 /api/v1 的调用,则可指定入口资源。

熔断降级:防止级联雪崩

当依赖的服务出现不稳定时,如果不加以隔离,调用方会因为等待超时或处理异常而堆积线程,最终耗尽资源导致自身不可用。Sentinel 的熔断降级策略有三种:

1. 慢调用比例 (SLOW_REQUEST_RATIO)

当资源的 慢调用比例 超过阈值,且统计时长内的请求数达到最小请求数,则触发熔断。

参数说明

  • 最大 RT:响应时间超过该值称为慢调用。
  • 比例阈值:慢调用占所有调用的比例。
  • 熔断时长:熔断持续的时间,之后尝试放行一个探测请求。
  • 最小请求数:统计周期内至少需要的请求数。

示例:设置最大 RT=200ms,比例阈值=0.5,最小请求数=5,熔断时长=10 秒。若 1 秒内出现 5 个请求,其中 3 个 RT>200ms(比例=0.6),则触发熔断,之后 10 秒内所有请求直接失败。

2. 异常比例 (ERROR_RATIO)

当资源的 异常比例 超过阈值,且请求数≥最小请求数时触发熔断。适用于依赖服务频繁抛出异常的情况。

3. 异常数 (ERROR_COUNT)

当 1 分钟内异常数超过阈值直接熔断。注意统计时间窗口是分钟级别,相对较少使用。

编码实现熔断降级

以慢调用比例为例,定义一个模拟远程调用的接口:

@GetMapping("/remote")
@SentinelResource(value = "remoteService",
                  fallback = "remoteFallback")
public String callRemote() throws InterruptedException {
    // 模拟随机延迟
    long sleepTime = new Random().nextInt(500);
    Thread.sleep(sleepTime);
    return "remote response";
}

// fallback 处理异常或熔断
public String remoteFallback(Throwable t) {
    return "服务降级,请稍后重试";
}

在 Sentinel 控制台为 remoteService 资源添加降级规则(熔断):

  • 降级策略:慢调用比例
  • 最大 RT:100ms
  • 比例阈值:0.3
  • 最小请求数:5
  • 熔断时长:5 秒

使用压测工具发送多次请求,当慢调用比例满足条件时,控制台会显示资源处于熔断状态,请求直接进入 fallback 逻辑。


系统自适应保护

除了针对资源的规则,Sentinel 还提供系统层面的保护规则,从整体维度控制入口流量:

  • Load:仅对 Linux/Unix 有效,当系统 load1 超过阈值时触发保护。
  • CPU 使用率:系统 CPU 使用率超过阈值时保护。
  • 平均 RT:所有入口流量的平均 RT 过高时保护。
  • 并发线程数:所有入口并发线程数过高时保护。
  • 入口 QPS:总入口 QPS 过高时保护。

这些规则不需要针对单一资源,是从集群大局出发的兜底策略。


规则持久化

默认情况下,Sentinel 规则存储在内存中,应用重启即丢失。生产环境推荐使用配置中心(如 Nacos)进行持久化。以 Nacos 为例:

添加依赖:

<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-config</artifactId>
</dependency>

配置 application.yml

spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            data-id: ${spring.application.name}-sentinel
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow   # 持久化流控规则