Sentinel 限流熔断学习:配置策略、限流算法对比与适用场景

摘要:本文从微服务为什么需要限流与熔断讲起,系统介绍 Sentinel 的流控规则、熔断降级规则、热点参数限流与系统保护等核心配置策略;深入对比固定窗口、滑动窗口、漏桶、令牌桶四大限流算法的原理、优缺点与适用场景,并给出每种算法在 Sentinel 中的对应实现,最后附上实战配置建议。


一、为什么需要限流与熔断

随着微服务架构的普及,服务之间的调用链路越来越长:一个请求可能要经过网关、用户服务、订单服务、库存服务等多个节点。任何一个节点的抖动都可能被放大,最终引发服务雪崩(Cascade Failure)

举个常见的例子:

  1. 用户服务 A 调用订单服务 B,B 响应变慢;
  2. A 的线程池被慢请求占满,A 自己也变慢;
  3. 调用 A 的上游服务 C 随之被拖垮;
  4. 雪崩就这样沿着调用链一路传播下去。

应对雪崩有三板斧:

  • 限流(Rate Limiting):控制请求的进入速度,把流量挡在系统容量之外;
  • 熔断(Circuit Breaking):下游不可用时快速切断调用,避免无限等待;
  • 降级(Degradation):提供兜底逻辑,保证核心功能可用、非核心功能可牺牲。

Sentinel 正是阿里巴巴开源的一款以"流量"为切入点的稳定性组件,从流量控制、熔断降级、系统负载保护等多个维度保障服务的稳定性,并且经历了双十一大促等核心场景的长期考验。


二、Sentinel 核心概念与整体架构

2.1 两个组成部分

Sentinel 分为两部分:

组成部分 说明
核心库(Java 客户端) 不依赖任何框架,可运行于所有 Java 运行时环境,对 Spring Cloud、Dubbo、gRPC 等提供良好支持
控制台(Dashboard) 基于 Spring Boot 开发,开箱即用,提供实时监控、机器发现、规则管理等能力

2.2 资源与规则

Sentinel 的核心思想是:开发者只需要关注"资源"的定义,规则可以随时动态追加

  • 资源(Resource):被 Sentinel 保护的入口,可以是接口、方法、甚至一段代码;
  • 规则(Rule):定义如何保护资源,包括流控规则、熔断规则、热点规则、系统规则、授权规则等。

规则可以通过控制台在线配置,也可以通过代码 API 加载,还可以接入 Nacos、Apollo 等配置中心实现动态持久化。

2.3 Sentinel 与 Hystrix 对比

能力 Sentinel Hystrix
隔离策略 信号量隔离 线程池隔离 / 信号量隔离
熔断策略 响应时间、慢调用比例、异常比例、异常数 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于 RxJava)
限流能力 基于 QPS,支持调用关系限流 有限支持
流量整形 慢启动(Warm Up)、匀速排队 不支持
系统负载保护 支持 不支持
控制台 开箱即用,监控、规则、机器发现齐全 不完善
常见框架适配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

三、限流算法详解与对比

这是本文的重点。限流算法决定了"什么时候拒绝、拒绝多少、流量是否平滑",理解它们才能选对配置策略。

3.1 固定窗口算法(计数器算法)

原理:

将时间划分为固定长度的窗口(比如 1 秒),每个窗口内维护一个计数器:

  • 请求进来,计数器 +1;
  • 计数器超过阈值,直接拒绝;
  • 窗口结束,计数器清零,进入下一个窗口。
text 复制代码
窗口1(0~1s)         窗口2(1~2s)
[|||||||] 7个请求     [|||||||] 7个请求
阈值 = 5,窗口2内第6个请求被拒绝

优点:

  • 实现极其简单,内存占用小;
  • 性能好,适合高并发下的粗略限流。

缺点:

存在著名的临界问题:在窗口边界处,两个窗口内的请求可以瞬间"合流",造成 2 倍阈值的突发流量。

text 复制代码
阈值 = 100 QPS
0.9s~1.0s 通过 100 个请求
1.0s~1.1s 又通过 100 个请求
→ 0.2s 内实际通过了 200 个请求!

适用场景:

  • 对精度要求不高、实现优先的简单限流;
  • 统计类的粗略计数场景。

3.2 滑动窗口算法

原理:

滑动窗口是固定窗口的改进版:把窗口细分成 N 个小格子(样本窗口),每个格子独立计数,统计时滑动当前窗口并累加所有格子的计数。

text 复制代码
时间轴:  |0.0|0.1|0.2|0.3|0.4|0.5|0.6|0.7|0.8|0.9|  (秒)
窗口向右滑动,始终统计最近 1 秒内的所有格子之和

格子切得越细,统计越平滑,逼近真正的"滑动时间窗"。

优点:

  • 解决了固定窗口的临界突发问题;
  • 精度可控(格子越细精度越高)。

缺点:

  • 实现复杂度高于固定窗口;
  • 内存占用随格子数量增加。

适用场景:

  • 通用接口限流,是最普适的方案;
  • 秒杀、热点数据等对瞬时突发敏感的流量防护。

Sentinel 对应 :Sentinel 默认的限流统计就是基于滑动窗口实现的(DefaultController,即"快速失败"模式)。

3.3 漏桶算法(Leaky Bucket)

原理:

想象一个底部有洞的桶:

  • 请求像水一样倒入桶中;
  • 桶以固定速率向外漏出(处理请求);
  • 桶满了之后,新来的请求直接丢弃。
text 复制代码
请求进来 ──► ╭─────────╮
             │ 桶(队列)│ ──► 固定速率处理
桶满则丢弃    ╰─────────╯

优点:

  • 输出速率绝对恒定,是最好的"流量整形"工具;
  • 能有效削峰填谷,保护下游系统。

缺点:

  • 无法应对突发流量:即使桶是空的,也不能加速处理积压请求;
  • 突发流量会排队等待,可能增大响应延迟。

适用场景:

  • 对接有明确 QPS 限制的第三方 API;
  • 消息消费、数据库写入等需要严格控制速率、平滑流量的场景;
  • 削峰填谷类业务(如秒杀下单后异步落库)。

Sentinel 对应 :流控效果中的**排队等待(匀速排队)**就是漏桶算法的实现(RateLimiterController)。

3.4 令牌桶算法(Token Bucket)

原理:

系统以固定速率向桶中放入令牌,桶有容量上限:

  • 请求到达时,从桶中取一个令牌,取到则放行;
  • 取不到令牌则拒绝(或等待);
  • 桶中积攒的令牌可以被一次性消费,因此允许一定程度的突发
text 复制代码
令牌以 r 个/秒的速率放入 ──► ╭─────────╮
                             │ 令牌桶    │ ◄── 请求来取令牌,取到放行
                             ╰─────────╯
桶容量 = b,最多允许 b 个突发

优点:

  • 兼顾平均速率限制突发流量容忍,非常灵活;
  • 是业界最常用的限流算法之一(如 Guava RateLimiter、Spring Cloud Gateway 的 RequestRateLimiter)。

缺点:

  • 实现相对复杂;
  • 突发流量可能超过预期(burst 上限需要仔细调参)。

适用场景:

  • 允许短暂突发、但长期平均速率受限的场景,如 Web 入口、API 网关;
  • 需要"冷启动预热"的场景(系统刚启动时逐步放开流量)。

Sentinel 对应 :流控效果中的 Warm Up(预热) 参考了 Guava 令牌桶实现(WarmUpController),热点参数限流也使用了令牌桶思路。

3.5 四大算法对比总结

算法 实现复杂度 允许突发 流量平滑 临界问题 典型应用
固定窗口 差(窗口边界可翻倍) 粗略计数、简单限流
滑动窗口 基本解决 通用接口限流、秒杀防护
漏桶 强(恒定速率) 削峰填谷、对接第三方 API
令牌桶 允许(有上限) 网关入口、平均限速+突发

3.6 算法选择建议

  • 不知道选什么:默认用滑动窗口(Sentinel 默认快速失败),能覆盖 90% 的接口限流场景;
  • 流量必须绝对平滑:选漏桶(排队等待),保护下游数据库、第三方接口;
  • 允许突发但要限平均速率:选令牌桶(Warm Up / 自定义),适合网关与入口;
  • 对边界突发零容忍:避免固定窗口,改用滑动窗口或更细的窗口。

四、Sentinel 限流配置策略

4.1 快速接入

  1. 引入依赖:
xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>${spring-cloud-alibaba.version}</version>
</dependency>
  1. 下载并启动控制台:
bash 复制代码
java -jar sentinel-dashboard-1.8.3.jar

默认地址 http://localhost:8080,账号密码均为 sentinel

  1. 配置控制台地址:
yaml 复制代码
spring:
  application:
    name: mdx-shop-user
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080   # Sentinel Dashboard 地址
feign:
  sentinel:
    enabled: true

访问一次服务接口后,控制台即可看到监控到的资源。

4.2 流控规则属性

属性 说明
资源名 资源的唯一名称,默认是请求路径
针对来源 针对调用方限流,填写微服务名,默认 default(不区分来源)
阈值类型 QPS(每秒请求数)或 并发线程数
单机阈值 达到该阈值即触发限流
是否集群 是否启用集群流控
流控模式 直接 / 关联 / 链路
流控效果 快速失败 / Warm Up / 排队等待

4.3 三种流控模式

1. 直接(默认)

资源自身的 QPS/线程数达到阈值,直接限流。适合对单个接口做能力上限保护。

2. 关联

关联资源达到阈值时,限流自己。典型场景:

text 复制代码
读接口 /order/read
写接口 /order/write  ← 给读接口配置"关联"到写接口

当写接口 QPS 过高(数据库压力大)时,自动限流读接口,保护数据库。

3. 链路

只统计从指定入口资源进入的流量。适合针对来源做更精细的限流,例如同一个方法被多个上游调用时,只限制来自某个入口的流量。

4.4 三种流控效果

流控效果决定了触发阈值后请求如何处理,每种效果对应一种算法

流控效果 对应算法 行为
快速失败 滑动窗口 达到阈值后直接拒绝,抛出 FlowException,默认效果
Warm Up 令牌桶(预热) 冷启动时阈值从 阈值/coldFactor(默认 3)开始,经过预热时长逐步达到设定阈值,适合系统冷启动
排队等待 漏桶 请求以均匀速度通过,超时时间内排队,超过则拒绝;只支持 QPS 阈值类型,可配置排队超时时间

Warm Up 示意图:

text 复制代码
QPS
  │                  ┌──── 目标阈值(如 100)
  │                ┌─┘
  │             ┌──┘
  │          ┌──┘
  │  ┌───────┘   ← 预热期内从 100/3 ≈ 33 逐步上升
  └─────────────────────────────► 时间
    0        预热时长(如 10s)

4.5 代码方式配置流控规则

除了控制台,还可以通过代码加载规则,适合测试与自动化场景:

java 复制代码
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import java.util.Collections;

public class FlowRuleConfig {

    public static void initFlowRules() {
        FlowRule rule = new FlowRule();
        rule.setResource("getOrderNoResource");   // 资源名
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 阈值类型:QPS
        rule.setCount(10);                        // 单机阈值:每秒最多 10 个请求
        rule.setLimitApp("default");              // 针对来源:不区分来源
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 快速失败

        // 排队等待示例:匀速放行,最大排队 500ms
        // rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
        // rule.setMaxQueueingTimeMs(500);

        FlowRuleManager.loadRules(Collections.singletonList(rule));
    }
}

4.6 @SentinelResource 注解与兜底处理

用注解定义资源,并配置限流/熔断的兜底方法:

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("getOrderNo")
    @SentinelResource(
        value = "getOrderNoResource",
        blockHandler = "getOrderNoBlockHandler",
        blockHandlerClass = UserController.class
    )
    public String getOrderNo(String userId, String tenantId, HttpServletRequest request) {
        return userService.getOrderNo(userId, tenantId, request);
    }

    /**
     * 限流兜底方法:返回类型与原方法一致,
     * 参数与原方法匹配,最后追加 BlockException 参数。
     */
    public static String getOrderNoBlockHandler(String userId, String tenantId,
                                                HttpServletRequest request,
                                                BlockException e) {
        return "不好意思,前方拥挤,请您稍后再试";
    }
}

注解常用属性:

属性 说明
value 资源名称,必填
entryType 流量方向,IN / OUT,默认 OUT
blockHandler 处理 BlockException(限流、熔断触发)的方法名
blockHandlerClass blockHandler 所在类,跨类时该方法必须 static
fallback 处理业务异常的方法名(可带 Throwable 参数)
fallbackClass fallback 所在类,跨类时必须 static
defaultFallback 通用兜底,fallback 优先于它
exceptionsToIgnore 指定忽略的异常,不统计、不进兜底,原样抛出

注意:blockHandler 处理的是 Sentinel 触发的 BlockException(限流/熔断),fallback 处理的是业务方法自身抛出的异常,两者职责不同。


五、Sentinel 熔断降级配置策略

5.1 熔断器状态机

Sentinel 的熔断器有三个状态,与主流熔断框架(如 Hystrix、Resilience4j)一致:
#mermaid-svg-HPWE84taoXdvuLAB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HPWE84taoXdvuLAB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HPWE84taoXdvuLAB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HPWE84taoXdvuLAB .error-icon{fill:#552222;}#mermaid-svg-HPWE84taoXdvuLAB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HPWE84taoXdvuLAB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HPWE84taoXdvuLAB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HPWE84taoXdvuLAB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HPWE84taoXdvuLAB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HPWE84taoXdvuLAB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HPWE84taoXdvuLAB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HPWE84taoXdvuLAB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HPWE84taoXdvuLAB .marker.cross{stroke:#333333;}#mermaid-svg-HPWE84taoXdvuLAB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HPWE84taoXdvuLAB p{margin:0;}#mermaid-svg-HPWE84taoXdvuLAB defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-HPWE84taoXdvuLAB g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-HPWE84taoXdvuLAB g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-HPWE84taoXdvuLAB g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-HPWE84taoXdvuLAB g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-HPWE84taoXdvuLAB g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-HPWE84taoXdvuLAB .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-HPWE84taoXdvuLAB .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-HPWE84taoXdvuLAB .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-HPWE84taoXdvuLAB .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-HPWE84taoXdvuLAB .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-HPWE84taoXdvuLAB .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-HPWE84taoXdvuLAB .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-HPWE84taoXdvuLAB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HPWE84taoXdvuLAB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HPWE84taoXdvuLAB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HPWE84taoXdvuLAB .edgeLabel .label text{fill:#333;}#mermaid-svg-HPWE84taoXdvuLAB .label div .edgeLabel{color:#333;}#mermaid-svg-HPWE84taoXdvuLAB .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-HPWE84taoXdvuLAB .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-HPWE84taoXdvuLAB .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-HPWE84taoXdvuLAB .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-HPWE84taoXdvuLAB .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-HPWE84taoXdvuLAB .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HPWE84taoXdvuLAB .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HPWE84taoXdvuLAB #statediagram-barbEnd{fill:#333333;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HPWE84taoXdvuLAB .cluster-label,#mermaid-svg-HPWE84taoXdvuLAB .nodeLabel{color:#131300;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-HPWE84taoXdvuLAB .note-edge{stroke-dasharray:5;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-note text{fill:black;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram-note .nodeLabel{color:black;}#mermaid-svg-HPWE84taoXdvuLAB .statediagram .edgeLabel{color:red;}#mermaid-svg-HPWE84taoXdvuLAB #dependencyStart,#mermaid-svg-HPWE84taoXdvuLAB #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-HPWE84taoXdvuLAB .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HPWE84taoXdvuLAB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 统计周期内指标超过阈值
熔断时长结束
探测请求成功
探测请求失败
CLOSED
OPEN
HALF_OPEN

  • CLOSED(关闭):正常放行,持续统计指标;
  • OPEN(打开):熔断生效,请求直接降级,不再调用下游;
  • HALF_OPEN(半开):熔断时长结束后放行一个探测请求,成功则恢复,失败则再次熔断。

5.2 三种熔断策略

1. 慢调用比例(SLOW_REQUEST_RATIO)

  • 设置允许的最大 RT(慢调用阈值);
  • 统计时长内请求数超过最小请求数,且慢调用比例超过阈值,则触发熔断;
  • 恢复后放行一个探测请求,若其 RT 小于慢调用阈值则恢复,否则再次熔断。

2. 异常比例(ERROR_RATIO)

  • 统计时长内请求数超过最小请求数,且异常比例超过阈值(范围 [0.0, 1.0])则熔断;
  • 探测请求成功则恢复,失败则再次熔断。

3. 异常数(ERROR_COUNT)

  • 统计时长内异常数超过阈值则熔断;
  • 探测请求成功则恢复,失败则再次熔断。

5.3 控制台配置步骤

以慢调用比例为例,在控制台"熔断规则 → 新增"中配置:

配置项 示例值 说明
资源名 sentinelAResource @SentinelResource 的 value 一致
熔断策略 慢调用比例 三种策略之一
最大 RT 200 ms 响应时间超过则记为慢调用
比例阈值 0.1 慢调用占比超过 10% 触发熔断
最小请求数 5 统计周期内请求数必须大于该值才判定
统计时长 2 秒 指标统计窗口
熔断时长 5 秒 熔断器打开的时间,结束后进入半开探测

提示:Sentinel 默认统计的 RT 上限是 4900ms,超过部分按 4900ms 计算;如需调整,可通过启动参数 -Dcsp.sentinel.statistic.max.rt=xxx 修改。

5.4 代码方式配置熔断规则

java 复制代码
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import java.util.Collections;

public class DegradeRuleConfig {

    public static void initDegradeRules() {
        DegradeRule rule = new DegradeRule();
        rule.setResource("sentinelAResource");     // 资源名
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); // 熔断策略:慢调用比例
        rule.setCount(200);                        // 最大 RT:200ms
        rule.setSlowRatioThreshold(0.1);           // 慢调用比例阈值:10%
        rule.setMinRequestAmount(5);               // 最小请求数
        rule.setStatIntervalMs(2000);              // 统计时长:2s
        rule.setTimeWindow(5);                     // 熔断时长:5s

        DegradeRuleManager.loadRules(Collections.singletonList(rule));
    }
}

配套兜底方法:

java 复制代码
@Component
public class UserSentinelResourceHandler {

    /**
     * fallback 兜底方法:方法名与 @SentinelResource 中配置一致,必须 static。
     */
    public static String sentinelAResource(Throwable throwable) {
        return "触发熔断,服务暂不可用,请稍后重试";
    }
}

5.5 熔断策略怎么选

场景 推荐策略
下游响应变慢,需要按 RT 感知 慢调用比例
依赖方大量报错(如 5xx、业务异常) 异常比例
异常绝对值更直观、数量稳定 异常数
需要兼顾慢调用与异常 优先慢调用比例 + 异常比例组合

六、进阶:热点参数限流与系统保护

6.1 热点参数限流

热点参数限流针对参数维度做限流,例如:同一个商品 ID 被大量访问时只限制该商品,而不是限制整个接口。

控制台配置要点:

  • 资源名:与方法上 @SentinelResource 的 value 一致;
  • 参数索引:第几个参数(0 开始);
  • 单机阈值:单个参数值每秒最大访问量;
  • 参数例外项:为特定参数值单独设置阈值。
java 复制代码
@GetMapping("/hotspot")
@SentinelResource(
    value = "hotspotResource",
    blockHandler = "hotspotResource",
    blockHandlerClass = UserSentinelResourceHandler.class
)
public String hotspot(@RequestParam(value = "userId", required = false) String userId,
                      @RequestParam(value = "shopId", required = false) String shopId) {
    return "我是hotspot";
}

// 兜底方法
public static String hotspotResource(String userId, String shopId, BlockException e) {
    return "您被认为恶意访问,触发热点限流";
}

6.2 系统保护规则

系统规则从应用入口维度进行保护,监控单台机器的:

  • load(系统负载,仅 Linux/Unix 生效);
  • CPU 使用率;
  • 平均 RT;
  • 入口 QPS;
  • 并发线程数。

当任意指标超过阈值时,所有入口流量都会被限流,让系统"跑在最大吞吐量的同时保持稳定"。适合作为兜底保护,但注意它作用于整个应用,配置时要保守。


七、最佳实践建议

  1. 资源命名统一 :优先用 @SentinelResource 显式命名资源,避免路径变化导致规则失效;业务兜底与异常兜底分开写(blockHandler / fallback)。
  2. 限流算法按场景选:通用接口用默认滑动窗口(快速失败);需要平滑流量用排队等待(漏桶);系统冷启动用 Warm Up(令牌桶)。
  3. 熔断阈值要基于压测:不要拍脑袋定 RT 和比例,先压测拿到正常 RT 的 P99,再设置慢调用阈值,通常取 P99 的 1.5~2 倍留出缓冲。
  4. 熔断时长不宜过短:至少给下游 5~10 秒恢复窗口,避免频繁开合(振荡)。
  5. 规则动态化:生产环境通过 Nacos/Apollo 管理规则,支持热更新与持久化,避免重启丢失。
  6. 先监控后限流:上线前先观察控制台监控数据,确认正常流量基线,再配置阈值。
  7. 限流兜底要友好:用户侧返回提示要语义明确(如"系统繁忙,请稍后再试"),并做好日志埋点便于排查。

八、总结

本文围绕 Sentinel 的限流与熔断,梳理了完整的配置策略:

  • 流控规则:阈值类型(QPS/线程数)、流控模式(直接/关联/链路)、流控效果(快速失败/Warm Up/排队等待);
  • 熔断规则:慢调用比例、异常比例、异常数三种策略,以及 CLOSED → OPEN → HALF_OPEN 的恢复机制;
  • 热点参数限流与系统保护:参数级限流与应用级兜底。

同时对比了四大限流算法:

算法 一句话总结 优先选它的场景
固定窗口 实现最简单,但有临界突发 粗略限流、不计较精度
滑动窗口 通用且精确,Sentinel 默认方案 常规接口、秒杀、热点
漏桶 输出恒定,完美削峰填谷 保护第三方 API、数据库写入
令牌桶 限平均速率,允许突发 网关入口、冷启动预热

没有"最好"的算法,只有"最合适"的场景。理解了算法差异,再结合压测数据配置规则,Sentinel 才能真正成为服务稳定性的守护者。


本文参考了 Sentinel 官方文档整理而成。

相关推荐
成为你的宁宁1 小时前
【Sentinel部署与流量防护】
sentinel
952361 天前
Sentinel
java·后端·spring·sentinel·springcloud
渣渣盟2 天前
当 Redis 集群发生主从切换(Failover)时,Flink 任务会崩溃吗?如何利用 Sentinel 实现高可用?
redis·flink·sentinel
xiaoxiangsiyan8 天前
LNMP + Redis Sentinel 高可用架构部署手册(续)
运维·网络·数据库·redis·缓存·架构·sentinel
敲代码的嘎仔8 天前
从零搭建微服务:Spring Cloud Alibaba 全家桶踩坑实录(Nacos + OpenFeign + Gateway + Sentinel)
java·spring boot·spring·spring cloud·微服务·gateway·sentinel
小罗水11 天前
第14章 Sentinel 限流与 AI 降级
人工智能·sentinel
he___H11 天前
Sentinel使用实操
java·开发语言·sentinel
随风M记忆s12 天前
GEE&Python-demo:利用Sentinel-监测北京奥林匹克森林公园年NDVI变化(附Python版)
开发语言·python·sentinel
X-⃢_⃢-X12 天前
六、Sentinel
网络·数据库·sentinel