乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 微服务与 Spring Cloud 概述

    • 微服务与 Spring Cloud 概述
  • 第2章 服务注册与发现

    • Eureka 服务注册与发现
    • Consul 服务注册与发现
  • 第3章 客户端负载均衡

    • Ribbon 客户端负载均衡
    • Spring Cloud LoadBalancer
  • 第4章 声明式服务调用

    • Feign 声明式 HTTP 客户端
    • OpenFeign 高级特性与 Spring Cloud 集成
  • 第5章 服务容错与熔断

    • Resilience4j 服务容错与熔断
    • Sentinel 流量控制与熔断降级
  • 第6章 配置中心

    • Spring Cloud Config 配置中心
  • 第7章 API 网关

    • Spring Cloud Gateway 现代化 API 网关
    • Zuul 网关(已进入维护模式)
  • 第8章 消息驱动的微服务

    • Spring Cloud Stream 消息驱动的微服务
  • 第9章 分布式追踪与监控

    • Sleuth + Zipkin 分布式链路追踪
  • 第10章 最佳实践与面试考点

    • Spring Cloud 最佳实践与面试考点

Sentinel 流量控制与熔断降级

导学

Resilience4j 熔断器上线后,系统稳定性明显提升。但产品经理孔蓝又来了:"双十二我们要搞秒杀活动,预计 QPS 是平时的 10 倍。能不能让系统在超过承载能力时,直接拒绝多余的流量,而不是等系统崩溃后再熔断?"

白歌点点头:"这是限流(Rate Limiting)的诉求。阿里巴巴开源的 Sentinel 在这方面比 Resilience4j 更强大——它把限流作为一等公民,而且提供实时监控面板。"


定位与问题场景

需求Resilience4j 方案Sentinel 方案
限流Rate Limiter(简单 QPS 限制)多种限流策略(QPS/并发线程数/热点参数/集群限流)
熔断基于失败率的简单熔断基于响应时间、慢调用比例、异常比例的多维熔断
流量整形无匀速排队(漏桶)、Warm Up(令牌桶预热)
实时监控需通过 Micrometer → Prometheus → Grafana内置 Sentinel Dashboard
规则动态下发需重启或通过配置中心Dashboard 实时推送 + Nacos 持久化

Sentinel 核心原理

整体架构

核心概念

概念说明
资源(Resource)被保护的代码块或接口,如 /order/create
规则(Rule)针对资源的限流/熔断策略
Entry进入资源的令牌,SphU.entry("resourceName")
Slot Chain责任链模式,每个 Slot 负责一种检查
Context调用上下文,携带调用来源等信息

限流算法对比


完整示例:飞翔科技秒杀接口限流与熔断

场景描述

秒杀活动期间,订单创建接口 QPS 从平时的 200 飙升至 2000。使用 Sentinel 限流 + 熔断保护。

操作前后对比:

维度引入 Sentinel 前引入 Sentinel 后
秒杀 QPS 2000数据库连接池耗尽,全站崩溃超出 QPS 阈值直接拒绝,核心链路正常
支付服务慢线程堆积,OOM慢调用比例熔断,快速降级
监控人工巡检日志Dashboard 实时查看 QPS/RT

步骤一:依赖引入

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

步骤二:基础配置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080    # Sentinel Dashboard 地址
        port: 8719                   # 本机与 Dashboard 通信端口
      eager: true                    # 饥饿加载,启动时注册

步骤三:限流——@SentinelResource 注解

@RestController
public class SeckillController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/seckill/{productId}")
    @SentinelResource(
        value = "seckill",                    // 资源名
        blockHandler = "seckillBlocked",      // 限流/降级触发时调用的方法
        fallback = "seckillFallback"          // 业务异常时调用的方法
    )
    public Map<String, Object> seckill(
            @PathVariable Long productId,
            @RequestParam Long userId) {
        return orderService.createSeckillOrder(userId, productId);
    }

    // blockHandler:仅处理限流/降级异常(BlockException)
    public Map<String, Object> seckillBlocked(
            Long productId, Long userId, BlockException e) {
        return Map.of(
            "code", 429,
            "message", "秒杀活动太火爆了,请稍后再试!"
        );
    }

    // fallback:处理业务异常(不含 BlockException)
    public Map<String, Object> seckillFallback(
            Long productId, Long userId, Throwable e) {
        log.error("秒杀业务异常", e);
        return Map.of("code", 500, "message", "系统异常");
    }
}

步骤四:Sentinel Dashboard 配置规则

在 Dashboard(http://localhost:8080)中配置:

限流规则:

资源名阈值类型QPS 阈值流控模式效果
seckillQPS500直接超过 500 QPS 直接拒绝

熔断规则(慢调用比例):

资源名策略最大 RT比例阈值熔断时长
seckill慢调用比例200ms0.510s

当 50% 的请求响应时间超过 200ms 时触发熔断,10 秒后进入半开状态。

步骤五:代码配置规则(不依赖 Dashboard)

@PostConstruct
public void initFlowRules() {
    List<FlowRule> rules = new ArrayList<>();
    
    FlowRule rule = new FlowRule();
    rule.setResource("seckill");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);  // QPS 模式
    rule.setCount(500);                            // 阈值 500
    rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
    rules.add(rule);

    FlowRuleManager.loadRules(rules);
}

@PostConstruct
public void initDegradeRules() {
    List<DegradeRule> rules = new ArrayList<>();
    
    DegradeRule rule = new DegradeRule();
    rule.setResource("seckill");
    rule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());
    rule.setCount(200);      // 最大 RT 200ms
    rule.setSlowRatioThreshold(0.5);  // 慢调用比例 50%
    rule.setTimeWindow(10);  // 熔断时长 10s
    rule.setMinRequestAmount(5);
    rules.add(rule);

    DegradeRuleManager.loadRules(rules);
}

步骤六:Feign 集成 Sentinel

feign:
  sentinel:
    enabled: true    # 开启 Feign 的 Sentinel 支持
@FeignClient(
    name = "FEIXIANG-INVENTORY-SERVICE",
    fallback = InventoryClientFallback.class
)
public interface InventoryClient {
    @GetMapping("/inventory/{productId}")
    StockDTO getStock(@PathVariable("productId") Long productId);
}

易错场景

1. blockHandler 和 fallback 混淆

// blockHandler:仅处理 BlockException(限流/降级触发)
public Map blockHandler(Params..., BlockException e) { }

// fallback:处理所有异常(不含 BlockException)
public Map fallback(Params..., Throwable e) { }

// 两者可以同时指定,分别处理不同异常
@SentinelResource(value = "seckill", blockHandler = "...", fallback = "...")

2. blockHandler 方法签名错误

// ❌ 错误:缺少 BlockException 参数
public Map blockHandler(Long productId) { ... }

// ✅ 正确:原参数 + BlockException
public Map blockHandler(Long productId, Long userId, BlockException e) { ... }

3. Sentinel Dashboard 配置的规则重启丢失

Dashboard 中的规则默认存储在内存中,服务重启后丢失。生产环境必须持久化:

spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            data-id: ${spring.application.name}-sentinel-rules
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow

4. 与 @Transactional 混用时降级方法不生效

@SentinelResource 和 @Transactional 同方法时,由于 AOP 代理顺序问题,降级可能不生效。建议拆分为两个方法。


面试考点

Sentinel 的 blockHandler 和 fallback 有什么区别?

blockHandler 仅处理 Sentinel 规则触发(限流/降级)的 BlockException,方法签名需额外加 BlockException 参数。fallback 处理业务方法抛出的所有异常(不含 BlockException),方法签名仅与原方法参数一致。两者可同时使用,分别覆盖不同异常类型。

Sentinel 滑动窗口和令牌桶/漏桶的区别?

  • 滑动窗口:统计最近时间窗口内的请求数,超过阈值则限流。Sentinel 默认使用滑动窗口实现 QPS 限流
  • 令牌桶:以固定速率生成令牌,请求需获取令牌才放行,允许突发流量(Warm Up 效果)
  • 漏桶:请求进入队列,以固定速率流出(匀速排队效果),流量整形更平滑
  • Sentinel 同时支持三种效果:直接拒绝(滑动窗口)、Warm Up(令牌桶预热)、匀速排队(漏桶)

Sentinel 如何实现集群限流?

Sentinel 提供 Token Server 模式:部署独立的 Token Server 集群,所有客户端向 Token Server 请求令牌,Token Server 统一计数和限流。适合需要精确控制全局限流的场景(如整个集群秒杀接口总 QPS 不超过 5000)。

Sentinel vs Resilience4j 选型?

  • Sentinel:阿里出品,限流能力突出,Dashboard 可视化,中文文档丰富,适合国内中大型项目
  • Resilience4j:Netflix 推荐,轻量函数式,与 Spring 生态深度集成,适合纯熔断需求或海外项目
  • 技术栈已是 Spring Cloud Alibaba(Nacos + Sentinel)的选 Sentinel;追求轻量和 Spring 原生生态的选 Resilience4j

小结

Sentinel 以限流为核心,配合熔断降级、热点参数限流、集群限流等功能,在前置流量整形方面比 Resilience4j 更精细。实时 Dashboard 大幅降低了运维门槛,规则的动态下发避免了重启。至此,服务调用链路的前四环(注册发现 → 负载均衡 → 声明式调用 → 容错)已经完整,下一章进入配置中心——如何让几百个微服务的配置统一管理。

上一页
Resilience4j 服务容错与熔断