Alibaba Spring Cloud 十七 Sentinel熔断降级

时间:2025-01-25 18:56:10

概述
在微服务架构中,熔断与降级是保证系统稳定性的重要机制,能有效防止故障蔓延或雪崩效应。当某个服务出现异常、延迟过高或错误率过高时,触发熔断保护,将该服务“隔离”一段时间,避免影响整体系统的吞吐和可用性。
Spring Cloud Alibaba Sentinel 提供了灵活的熔断降级(Degrade)机制,可以根据响应时间(RT)异常比例异常数等指标,自动触发熔断并执行相应的降级策略,为业务提供及时的兜底处理。


1. 核心概念

  1. 资源(Resource)
    与流量控制类似,Sentinel 针对“资源”级别进行监控与保护。资源可以是一个接口、方法或任意需要保护的代码片段。
    在 Spring Cloud Alibaba 中,常见做法是通过 @SentinelResource 注解声明要保护的业务方法。

  2. 降级规则(Degrade Rule)
    Sentinel 的降级规则会根据一定的触发条件(如异常比例、异常数、平均响应时间等)将资源进行临时熔断,在设定的时间窗口内,对该资源的调用会被自动阻断或返回降级处理逻辑。

  3. 熔断窗口(Time Window)
    当触发熔断后,资源会进入一个“熔断窗口期”,在此期间内,所有对该资源的调用要么直接抛出异常,要么执行降级方法。
    熔断窗口结束后,Sentinel 会自动恢复对该资源的调用,若新的规则再次触发,则再次熔断。

  4. 降级策略(Degrade Strategy)
    Sentinel 提供了三种降级触发类型:

    • 慢调用比例 (DEGRADE_GRADE_RT):在过去一段时间(默认统计时长 1 分钟)内,如果某资源的平均响应时间超过阈值,并且慢调用比率也超过设定值,则触发熔断。
    • 异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):在统计时长内,如果资源的异常(抛出业务异常或运行时异常等)比例达到设定阈值,则触发熔断。
    • 异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):在统计时长内,如果异常总数达到或超过设定阈值,则触发熔断。

2. 常见熔断降级规则

  1. 平均响应时间(RT)超过阈值

    • 如果资源的平均响应时间持续高于某个设定阈值(如 1000ms),并且慢调用比率达到指定比例(默认为 1,即 100%),则熔断。
    • 适用于对响应时间敏感的场景,一旦响应过慢,就认为该服务已经不可用。
  2. 异常比例超过阈值

    • 适用于根据错误率判断服务是否健康的场景,例如设置异常比例阈值为 0.2(即 20%),如果统计周期内的异常数 / 总调用量 > 20%,则触发熔断。
    • 常用于识别服务出现大面积异常时快速熔断。
  3. 异常数超过阈值

    • 如果统计窗口内累计异常次数超过一定的绝对值阈值(如 10 次),触发熔断。
    • 适用于访问量不大但对异常数较为敏感的场景,或是想对错误数量进行硬性限制的情况。

3. 配置方式

3.1 通过 Sentinel 控制台动态配置

  1. 启动控制台

    • 下载或打包 Sentinel Dashboard 工程,默认端口一般是 8080
    • 访问 http://localhost:8080 进入控制台。
  2. 应用集成

    • pom.xml 中引入依赖(示例版本仅供参考):
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        <version>2.2.10.RELEASE</version>
      </dependency>
      
    • application.yml 中配置:
      spring:
        cloud:
          sentinel:
            transport:
              port: 8719
              dashboard: 127.0.0.1:8080
      
  3. 标记资源

    • 在需要进行熔断保护的方法或接口上,通过 @SentinelResource 声明资源:
      @RestController
      public class DemoController {
      
          @GetMapping("/testDegrade")
          @SentinelResource(value = "testDegradeResource",
                            blockHandler = "blockHandler",
                            fallback = "fallbackHandler")
          public String testDegrade(@RequestParam(required = false) String param) {
              // 这里故意模拟异常或延时
              if ("ex".equals(param)) {
                  throw new RuntimeException("触发异常");
              }
              return "Test Degrade Success";
          }
      
          // 限流、熔断等阻塞时进入此方法
          public String blockHandler(String param, BlockException ex) {
              return "Blocked by Sentinel: " + ex.getClass().getSimpleName();
          }
      
          // 业务异常时触发 fallback
          public String fallbackHandler(String param, Throwable ex) {
              return "Fallback: " + (ex == null ? "" : ex.getMessage());
          }
      }
      
  4. 在控制台配置降级规则

    • 在“降级规则”页面中,为资源 testDegradeResource 新增一条规则:
      • 资源名: testDegradeResource
      • 降级模式: RT / 异常比例 / 异常数
      • 阈值: 具体数值(如 RT = 1000ms 或 异常比例=0.2)
      • 触发后熔断时长: 可以设置为 5s、10s 等

保存规则后,应用会自动从控制台拉取配置,一旦触发降级,就会在熔断窗口内对该资源进行快速失败或返回降级逻辑。

3.2 通过代码硬编码/配置文件加载

同流量控制一样,也可以在 Spring Boot 应用启动时通过代码加载降级规则。例如:

@Configuration
public class SentinelDegradeConfig implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        initDegradeRules();
    }

    private void initDegradeRules() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource("testDegradeResource");
        // 设置为异常比例类型
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
        // 异常比例阈值,20%
        rule.setCount(0.2);
        // 熔断时长:10s
        rule.setTimeWindow(10);

        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

这种方式无需依赖控制台,但缺点是动态调整不够灵活。


4. 熔断触发后的处理

  1. blockHandler

    • 当资源被限流或熔断时,框架会抛出 BlockException,可在 @SentinelResource 中配置 blockHandler 指定处理逻辑。
    • 这个逻辑仅在被 Sentinel 阻断时生效(如限流、熔断触发)。
  2. fallback

    • 当资源本身运行异常或出现业务错误时,会进入 fallback 指定的方法。
    • 这在接口调用出现异常时会返回一个自定义“备用结果”,也可以解决部分业务异常的处理需求。
  3. 全局异常处理

    • 如果没有使用 @SentinelResource 注解,也可以通过 Spring MVC 的全局异常捕获来处理 BlockException

5. 与 Hystrix / Resilience4j 的对比

  • Hystrix

    • 早期 Spring Cloud 微服务常用的熔断组件,但目前处于维护模式,不再积极更新。
    • Sentinel 不仅提供熔断,还提供流控、系统保护和热点限流等更丰富的功能,并配有实时监控的控制台。
  • Resilience4j

    • 同样是一个轻量级的容错库,也有比较丰富的熔断、限流、隔离等功能。
    • Sentinel 在国内社区和阿里生态中应用较多,且控制台管理和监控较为完善。

6. 常见使用场景

  1. 高并发接口

    • 在访问量极大且敏感接口上,如果响应时间或者异常率激增,触发熔断可以快速返回备用响应,防止主逻辑被拖垮。
  2. 外部服务依赖

    • 当依赖的第三方服务出现延迟或大量错误时,及时对其熔断,避免占用线程资源影响核心业务。
  3. 大型促销 / 秒杀场景

    • 在大促活动下,如果某些核心服务出现了性能瓶颈或异常暴涨,可以通过熔断降级保护整体系统的稳定性。

7. 总结

  • 原理:通过统计资源的响应时间、异常数或异常率等指标,在达到阈值后启动熔断,在熔断窗口内直接拒绝或降级请求,降低对不稳定资源的依赖。
  • 优势:相比传统限流或熔断框架,Sentinel 除了熔断降级外还支持丰富的流控场景,结合控制台的可视化管理,使得配置和监控更加灵活。
  • 最佳实践
    1. 根据业务 SLA 设定合理的 RT / 异常率 阈值,避免误触发熔断。
    2. 与流控、热点限流、系统保护等功能配合使用,提供更全面的稳定性保障。
    3. 配合 @SentinelResourcefallback 或全局异常处理机制,实现业务定制化的降级响应。

通过 Spring Cloud Alibaba Sentinel 的熔断降级功能,我们可以在服务出现不稳定或故障时,及时阻断问题服务,避免雪崩效应,并对上游调用方返回友好的降级结果,保障微服务架构下的整体稳定性和可用性。