一、Sentinel 简介

1.1 什么是 Sentinel?

Sentinel(哨兵)是阿里巴巴开源的面向分布式服务架构的轻量级流量控制组件。它以流量为切入点,从流量控制熔断降级系统自适应保护等多个维度来保障微服务的稳定性。

核心特性

  • 丰富的应用场景:秒杀、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:提供实时的监控功能,可以在控制台中看到接入应用的单台机器秒级数据。
  • 广泛的开源生态:与 Spring Cloud、Dubbo、gRPC 等框架无缝整合。
  • 基于资源的控制:资源可以是任何东西,服务、服务里的方法,甚至是一段代码。

1.2 核心概念

  • 资源: Sentinel 的核心概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它服务,甚至可以是一段代码。
  • 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

二、快速开始

2.1 下载与安装

  1. 下载 Sentinel Dashboard
    从 GitHub Releases 页面下载最新版本的 sentinel-dashboard.jar

    # 示例:下载到 /usr/local/sentinel 目录
    wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar -P /usr/local/sentinel/
    
  2. 启动控制台

    cd /usr/local/sentinel
    # 默认端口 8080,可通过 --server.port 参数修改
    java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
    
  3. 访问控制台
    启动后,在浏览器访问 http://192.168.1.40:8080(请替换为您的服务器IP)。默认用户名和密码均为 sentinel

2.2 Spring Boot 项目集成

1. 引入依赖
在您的 Spring Boot 项目的 pom.xml 中添加以下依赖:

<!-- Sentinel 核心依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel 数据源(用于规则持久化,可选) -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency>
<!-- Actuator(用于暴露端点,便于监控) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2. 配置文件
application.yml 中配置 Sentinel Dashboard 地址和客户端信息:

spring:
  application:
    name: your-service-name
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.1.40:8080 # Sentinel Dashboard 地址
        port: 8719 # 客户端与控制台通信的端口,默认8719,冲突会自动+1
        heartbeat-interval-ms: 500 # 心跳间隔,500ms发送一次心跳到dashboard
      # 客户端IP,用于Dashboard识别。若不指定,Sentinel会自动分配一个。
      client-ip: 192.168.1.41
      # 懒加载模式控制。默认false(懒加载),true表示初始化容器后立即注册监控服务。
      eager: true
# 暴露Actuator端点,便于查看Sentinel状态
management:
  endpoints:
    web:
      exposure:
        include: '*'

3. 编写一个测试接口

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

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

    // 限流或降级时的处理函数
    public String blockHandlerForHello(BlockException ex) {
        return "请求过于频繁,请稍后再试!";
    }
}

4. 启动应用并查看
启动您的 Spring Boot 应用。首次访问 /hello 接口后,稍等片刻,即可在 Sentinel Dashboard 的“实时监控”和“簇点链路”页面看到您的应用和 hello 资源。

三、流量控制(Flow Control)

流量控制是 Sentinel 的核心功能之一,用于控制服务的 QPS 或并发线程数,防止服务被瞬时流量冲垮。

3.1 规则配置(控制台)

在 Dashboard 的“流控规则”页面,点击“新增流控规则”:

  • 资源名:需要限流的接口路径或 @SentinelResourcevalue,例如 /hello
  • 针对来源:默认为 default,表示对所有来源生效。可指定具体的调用方应用名。
  • 阈值类型
    • QPS:每秒请求数。在请求进入方法前进行拦截。
    • 并发线程数:同时处理请求的线程数。允许请求进入方法,若方法内已有超过阈值的线程在运行,则新请求被拦截。
  • 流控模式
    • 直接:当本资源达到阈值时,直接限流。
    • 关联:当关联的资源达到阈值时,限流本资源。例如,/write 操作关联 /read 资源,当 /read 流量过高时,限制 /write
    • 链路:针对调用链路的入口资源进行限流。例如,入口资源 Entrance1Entrance2 都调用了资源 A,可以只对从 Entrance1 来的调用进行限流。
  • 流控效果
    • 快速失败:直接抛出 FlowException,是默认效果。
    • Warm Up(预热):系统从低水位开始,逐步升至设定的 QPS 阈值,避免冷系统被压垮。预热时长内,阈值为 设定阈值 / 冷加载因子(默认为3)
    • 排队等待:让请求匀速通过,单机阈值为每秒处理的请求数,超时的请求将被拒绝。

3.2 代码示例:关联流控

假设有两个接口:/read(查询)和 /write(写入)。我们希望当 /read 的 QPS 过高时,对 /write 进行限流,以保障核心的写入功能。

  1. 在 Dashboard 为 /write 资源新增流控规则

    • 资源名:/write
    • 流控模式:关联
    • 关联资源:/read
    • 阈值类型:QPS
    • 单机阈值:1 (为了演示效果,设小一点)
  2. 测试
    使用压测工具(如 JMeter)快速访问 /read 接口,使其 QPS 超过 1。此时再访问 /write 接口,将会被限流。

四、熔断降级(Circuit Breaking)

熔断降级用于在调用链路中某个资源出现不稳定状态(如调用超时、异常比例升高)时,对这个资源的调用进行限制,让请求快速失败,避免影响到整个链路。

4.1 降级规则

在 Dashboard 的“降级规则”页面新增规则:

  • 降级策略
    1. 慢调用比例 (RT)
      • 最大 RT:允许的最大响应时间(毫秒)。
      • 比例阈值:超过最大 RT 的请求比例阈值(0.0-1.0)。
      • 最小请求数:触发熔断的最小请求数,窗口期内至少收到这么多请求才判断。
      • 熔断时长:触发熔断后,持续熔断的时间(秒)。

      规则:在统计时长内,请求数大于最小请求数,且慢调用比例大于阈值,则触发熔断。

    2. 异常比例
      • 比例阈值:异常请求比例的阈值(0.0-1.0)。
      • 其他参数同上。

      规则:在统计时长内,请求数大于最小请求数,且异常比例大于阈值,则触发熔断。

    3. 异常数
      • 异常数:异常请求数量的阈值。
      • 统计时长:通常设置为 1 分钟(60秒)。

      规则:在统计时长内,异常数超过阈值,则触发熔断。

4.2 代码示例:模拟慢调用

@RestController
public class DegradeController {

    @GetMapping("/slow")
    @SentinelResource(value = "slowApi", fallback = "slowFallback")
    public String slow() throws InterruptedException {
        // 模拟处理耗时
        Thread.sleep(2000); // 休眠2秒,制造慢调用
        return "Slow Response";
    }

    // 熔断降级的fallback方法
    public String slowFallback(Throwable e) {
        return "服务暂时不可用,请稍后重试 (触发降级)";
    }
}

配置降级规则

  • 资源名:slowApi
  • 降级策略:慢调用比例
  • 最大 RT:1000 (ms)
  • 比例阈值:0.5
  • 最小请求数:5
  • 熔断时长:10 (秒)

测试:快速请求 /slow 接口 5 次以上,由于响应时间超过 1 秒的比例超过 50%,该资源将在接下来的 10 秒内被熔断,所有请求直接走 slowFallback 方法。

五、热点参数限流(Param Flow Control)

热点参数限流是一种更细粒度的流控,能够对携带特定参数的请求进行限流。

5.1 规则配置

在 Dashboard 的“热点规则”页面新增规则:

  • 资源名:受保护的资源,如 @SentinelResource("hot") 中的 "hot"
  • 限流模式:目前仅支持 QPS 模式
  • 参数索引:从 0 开始,对应方法参数的顺序。
  • 单机阈值:对该热点参数的全局 QPS 阈值。
  • 统计窗口时长:统计流量的时间窗口长度(秒)。
  • 参数例外项:可为特定的参数值设置独立的阈值。

5.2 代码示例

@RestController
public class HotParamController {

    @GetMapping("/product")
    @SentinelResource(value = "getProductById", blockHandler = "handleHotParam")
    public String getProductById(@RequestParam Long id, @RequestParam String name) {
        return "Product ID: " + id + ", Name: " + name;
    }

    // 热点参数限流的处理函数,参数列表必须与原方法一致,最后加一个 BlockException 参数
    public String handleHotParam(Long id, String name, BlockException ex) {
        return "热点商品 [" + id + "-" + name + "] 访问过于频繁,请稍后再试!";
    }
}

配置热点规则

  • 资源名:getProductById
  • 参数索引:0 (表示对第一个参数 id 进行热点判断)
  • 单机阈值:5
  • 参数例外项:id=101 -> 阈值 100 (商品ID为101的爆款,允许更高QPS)

测试:频繁请求 /product?id=101&name=A/product?id=102&name=B。对于 id=102 的请求,QPS超过5会被限流;而对于 id=101 的请求,阈值是100,更宽松。

六、系统自适应保护(System Rule)

系统规则保护整个应用的整体入口流量,防止应用本身被拖垮。

6.1 规则类型

在 Dashboard 的“系统规则”页面配置:

  • LOAD:系统的 load1 负载值,作为启动自适应保护的阈值(仅 Linux/Unix 有效)。
  • RT:所有入口流量的平均响应时间。
  • 线程数:所有入口流量的并发线程数。
  • 入口 QPS:所有入口资源的 QPS。
  • CPU 使用率:当前系统的 CPU 使用率。

当任何一个指标超过阈值,所有入口流量都会触发限流。

七、@SentinelResource 注解详解

该注解用于定义资源,并提供处理限流/降级异常的灵活性。

// 最完整的示例
@SentinelResource(
        value = "resourceName", // 资源名称,Dashboard中配置规则的核心标识
        blockHandler = "blockHandlerMethod", // 针对 BlockException(流控、降级)的处理函数名
        blockHandlerClass = BlockExceptionHandler.class, // blockHandler 方法所在的类(默认为当前类)
        fallback = "fallbackMethod", // 针对所有异常(包括业务异常)的降级函数名
        fallbackClass = FallbackHandler.class, // fallback 方法所在的类
        exceptionsToIgnore = {IllegalArgumentException.class} // 指定忽略的异常,这些异常不会触发 fallback
)
public String yourBusinessMethod(String arg) {
    // 业务逻辑
    if ("bad".equals(arg)) {
        throw new IllegalArgumentException("Invalid argument");
    }
    return "success";
}

// BlockException 处理函数(必须在同一个类中,或通过 blockHandlerClass 指定)
// 参数列表必须与原方法一致,并在最后增加一个 BlockException 参数
public String blockHandlerMethod(String arg, BlockException ex) {
    return "被限流或降级了: " + ex.getClass().getSimpleName();
}

// Fallback 函数(必须在同一个类中,或通过 fallbackClass 指定)
// 参数列表必须与原方法一致,并在最后增加一个 Throwable 参数
public String fallbackMethod(String arg, Throwable throwable) {
    return "业务执行异常,进入降级: " + throwable.getMessage();
}

八、规则持久化(集成 Nacos)

默认规则存储在内存中,应用重启会丢失。生产环境需要持久化到配置中心,如 Nacos。

8.1 添加依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

8.2 修改配置文件

spring:
  cloud:
    sentinel:
      datasource:
        # 数据源名称,可自定义
        flow-rule:
          nacos:
            server-addr: 192.168.1.40:8848 # Nacos 地址
            dataId: ${spring.application.name}-flow-rules # 对应Nacos的Data ID
            groupId: SENTINEL_GROUP # 分组,默认 DEFAULT_GROUP
            data-type: json # 规则数据格式
            rule-type: flow # 规则类型: flow(流控), degrade(降级), system(系统), param-flow(热点), authority(授权)
        # 可以配置多个数据源,对应不同规则类型
        degrade-rule:
          nacos:
            server-addr: 192.168.1.40:8848
            dataId: ${spring.application.name}-degrade-rules
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: degrade

8.3 在 Nacos 中创建配置

在 Nacos 控制台创建配置,例如 Data ID 为 your-service-name-flow-rules,配置内容为 JSON 数组:

[
  {
    "resource": "/hello",
    "limitApp": "default",
    "grade": 1,
    "count": 10,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

JSON 字段说明

  • resource: 资源名。
  • limitApp: 来源应用,default 代表不区分来源。
  • grade: 阈值类型,0 代表线程数,1 代表 QPS。
  • count: 单机阈值。
  • strategy: 流控模式,0 直接,1 关联,2 链路。
  • controlBehavior: 流控效果,0 快速失败,1 Warm Up,2 排队等待。
  • clusterMode: 是否集群模式,默认 false

应用启动后,会自动从 Nacos 拉取规则并生效。在 Sentinel Dashboard 修改规则后,也会推送到 Nacos,实现双向同步。

九、总结

Sentinel 作为一款功能强大的流量治理组件,通过其清晰的流量控制熔断降级系统保护热点防护能力,为微服务架构提供了坚实的稳定性保障。结合 Dashboard 的可视化管理和 Nacos 的规则持久化,能够轻松应对高并发场景下的各种稳定性挑战。

最佳实践建议

  1. 从小处着手:先从核心接口配置流控和降级规则。
  2. 监控先行:充分利用 Dashboard 的实时监控,观察系统流量和异常。
  3. 规则动态调整:根据监控数据,适时调整规则阈值,避免误杀或防护不足。
  4. 做好降级:为关键资源设计合理的降级逻辑,保证核心链路可用。

通过本文的介绍和示例,您应该已经掌握了 Sentinel 的核心概念和基本用法。接下来,可以在您的微服务项目中实践,逐步构建起可靠的流量防护体系。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐