Bootstrap

Alibaba Spring Cloud 十四 Spring Cloud Gateway + Sentinel 实现限流、熔断、动态路由以及负载均衡、路径匹配等核心功能的综合指南

Spring Cloud Gateway 如何集成 Sentinel 来实现限流、熔断、动态路由以及负载均衡、路径匹配等核心功能的综合指南。该教程会从依赖引入、网关配置、Sentinel 规则定义到代码示例进行逐步说明。


一、Spring Cloud Gateway 与 Sentinel 概述

  • Spring Cloud Gateway:基于 Spring WebFlux 的网关解决方案,能够为微服务提供统一的路由、限流、熔断、安全、监控等功能。
  • Sentinel:阿里开源的一款高可用防护框架,提供灵活的流量控制、熔断降级、系统负载保护等功能,可与 Spring Cloud Gateway 深度整合,实现网关层的统一限流和熔断。

1.1 主要功能

  1. 动态路由:可通过配置或代码动态添加、删除、修改路由规则。
  2. 负载均衡:使用 lb://service-name URI 与 Spring Cloud LoadBalancer 集成,实现服务名到实例列表的自动发现与轮询。
  3. 路径匹配:基于 PathHostHeaderQuery 等多种 Predicates 进行灵活路由匹配。
  4. 限流与熔断:通过 Sentinel 在网关层对请求进行流控、熔断降级,保护下游服务。

二、工程依赖及基本配置

2.1 Maven 依赖

以下示例基于 Spring Cloud Alibaba 生态,需添加相应的依赖版本管理。例如(以 2021 版为参考):

<properties>
    <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- Spring Cloud Alibaba 依赖管理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- Spring Cloud 依赖管理 -->
        <!-- 其他相关 BOM 依赖,可视具体版本而定 -->
    </dependencies>
</dependencyManagement>

添加 GatewaySentinel Starter 依赖:

<dependencies>
    <!-- Spring Cloud Gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!-- Sentinel 整合 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

    <!-- 其他依赖,如 Spring Cloud LoadBalancer -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>

2.2 基础配置(application.yml)

下面是一个简单的 application.yml 示例,演示如何配置 Gateway 的路由和 Sentinel 的基础内容:

server:
  port: 8080

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 开启基于服务发现的自动路由
      routes:
        - id: inventory-route
          uri: lb://inventory-service
          predicates:
            - Path=/inventory/**
          filters:
            - StripPrefix=1
        - id: user-route
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1

    sentinel:
      transport:
        dashboard: 127.0.0.1:8080  # Sentinel Dashboard 地址
        port: 8719  # Sentinel 客户端端口,避免冲突可自行修改
      eager: true  # 是否在启动时立即初始化 Sentinel

# 指定Nacos或其他注册中心地址(若使用服务发现)
# spring:
#   cloud:
#     nacos:
#       discovery:
#         server-addr: 127.0.0.1:8848

说明:

  1. uri: lb://... 表示启用负载均衡,由 Spring Cloud LoadBalancer 或 Ribbon(老版本)对后端实例进行轮询。
  2. StripPrefix=1 用于删除路由转发时的第一级路径,如请求 /inventory/list 会被转发到下游服务 /list
  3. discovery.locator.enabled=true 表示自动根据注册中心(如 Nacos、Eureka 等)去生成路由规则,无需手动在配置文件中逐一写死。

三、集成 Sentinel 实现限流和熔断

3.1 网关层限流基本原理

  • Sentinel 提供了一个 Spring Cloud Gateway Starter 模块(已内置于 spring-cloud-starter-alibaba-sentinel 中),会自动注入 GatewayFlowRuleManagerGatewayCallbackManager 等组件。
  • 通过为网关路由或自定义资源指定限流规则,可以在网关层面对某条路由(或某个路径)进行 QPS / 并发数 限流、或在后端响应超时时触发熔断降级。

3.2 Gateway 规则模型

Sentinel 为 Gateway 定义了以下维度的限流规则:

  1. Route ID:按网关 Route 进行限流。
  2. URL Path:按具体路径匹配限流。
  3. Host / Method / Origin:支持更多维度,如请求的方法类型(GET/POST)、来源IP等。

3.3 配置示例(代码方式)

可以在 Spring Boot 项目的初始化阶段,编程式地为 Gateway 的路由添加限流规则:

@Configuration
public class GatewaySentinelConfig implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        initGatewayRules();
    }

    private void initGatewayRules() {
        // 限流规则示例:对 routeId = "inventory-route" 的 QPS 做限制
        GatewayFlowRule rule = new GatewayFlowRule("inventory-route")
                .setCount(10)       // QPS 阈值
                .setIntervalSec(1); // 统计时间窗口(秒)

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

inventory-route 的请求量超过 10 QPS 时,Sentinel 将触发限流逻辑,默认返回 HTTP 429 或 Sentinel 的自定义限流提示。

高级用法

  1. 指定限流维度(Path、Method、Host 等)。
  2. 配合 Nacos / Apollo 存储规则,动态更新限流配置。

3.4 熔断降级

除了限流,Sentinel 还支持基于 RT(响应时间)、异常比例、异常数等进行熔断。在 Gateway 场景中,可以对每个 Route 设置熔断规则:

private void initDegradeRules() {
    DegradeRule rule = new DegradeRule("inventory-route")
        .setGrade(RuleConstant.DEGRADE_GRADE_RT)   // 基于响应时间RT
        .setCount(2000)                            // RT 阈值,ms
        .setTimeWindow(10);                        // 熔断持续时间,秒

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

当调用 inventory-route 的平均响应时间超过 2000ms 时,将熔断 10 秒,在此期间所有请求会被快速失败或降级处理。

3.5 自定义限流、熔断处理器

默认情况下,触发限流或熔断后,Gateway 会返回类似:

{
  "code": 429,
  "message": "Sentinel Gateway Blocked"
}

若需自定义响应内容或跳转页面,可以通过 GatewayCallbackManager.setBlockHandler(...)setBlockHandlerClass(...) 设置:

GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
        Map<String, Object> rsp = new HashMap<>();
        rsp.put("code", 429);
        rsp.put("msg", "Too many requests, please try later.");
        return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(rsp));
    }
});

四、支持负载均衡和路径匹配

4.1 负载均衡

上文提到,Spring Cloud Gateway 通过 lb://service-name URI 与 Spring Cloud LoadBalancer 或 Ribbon(旧) 集成。

  • 当服务实例注册到注册中心(如 Nacos / Eureka)后,Gateway 能自动获取其 IP、端口列表并进行轮询。
  • 无需自行编写脚本或配置 IP:Port。

4.2 路由 Predicates 与 Filters

Spring Cloud Gateway 的核心是 Routes, Predicates, Filters

  1. Predicates:用来匹配请求的条件,如 Path, Host, Method, Header 等。
  2. Filters:可在路由前后做额外处理,如 StripPrefix, AddRequestHeader, RewritePath 等。

示例:自定义一个路由匹配 /admin/**,转发到 lb://auth-service/admin,并在请求头中添加自定义头:

spring:
  cloud:
    gateway:
      routes:
        - id: admin-route
          uri: lb://auth-service
          predicates:
            - Path=/admin/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Gateway-Request, Admin

此时对网关发起 GET /admin/user/list 请求,会自动转发到 auth-service/user/list


五、动态路由

5.1 配置方式

  1. 静态配置:在 application.yml 中写死路由规则。
  2. 基于服务发现spring.cloud.gateway.discovery.locator.enabled=true,自动为每个注册中心中的服务创建路由。
  3. 数据库 / 配置中心:将路由信息存在数据库或 Nacos Config / Apollo 中,动态刷新网关配置。
  4. 编程式管理路由:使用 RouteDefinitionWriterRouteDefinitionRepository 动态增删改查路由。

5.2 Sentinel + 动态路由

当我们修改或新增网关路由时,也可以动态更新对应的 Sentinel GatewayFlowRuleDegradeRule 规则,以便对新路由生效。常见做法:

  • 将 Gateway 路由与 Sentinel 限流规则一起存储在 Nacos Config 中;
  • 客户端监听配置变更后,更新路由配置与 Sentinel 规则。

六、完整示例小结

6.1 application.yml

server:
  port: 8080

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      # (可选) 静态定义一些路由
      routes:
        - id: user-route
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080
        port: 8719
      eager: true

6.2 GatewaySentinelConfig.java

@Configuration
public class GatewaySentinelConfig implements InitializingBean {

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

    private void initGatewayFlowRules() {
        GatewayFlowRule rule = new GatewayFlowRule("user-route")
                .setCount(5)         // QPS = 5
                .setIntervalSec(1);  // 1s 时间窗口
        GatewayRuleManager.loadRules(Collections.singletonList(rule));
    }

    private void initDegradeRules() {
        DegradeRule rule = new DegradeRule("user-route")
                .setGrade(RuleConstant.DEGRADE_GRADE_RT)
                .setCount(2000)   // RT阈值
                .setTimeWindow(10);
        DegradeRuleManager.loadRules(Collections.singletonList(rule));
    }

    private void initBlockHandler() {
        GatewayCallbackManager.setBlockHandler((exchange, t) -> {
            Map<String, Object> res = new HashMap<>();
            res.put("code", 429);
            res.put("message", "Request has been blocked by Sentinel Gateway");
            return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(BodyInserters.fromValue(res));
        });
    }
}

启动后,访问 http://localhost:8080/user/xxx 会被自动路由到 user-service 对应的实例,如果 QPS 超过 5 或平均响应时间超标,会触发 Sentinel 的限流或熔断逻辑。


七、常见问题与建议

  1. Sentinel Dashboard 无法显示网关信息

    • 确认 spring.cloud.sentinel.transport.dashboard=ip:port 正确且能连通。
    • 检查日志中是否有 Sentinel Default Transport Exception 等错误。
    • 需要在同一个版本兼容的情况下使用 Spring Cloud Alibaba + Sentinel Dashboard。
  2. 网关全局过滤器与 Sentinel 冲突

    • Spring Cloud Gateway 全局过滤器通常在 GlobalFilterFilter 中执行,如果有与 Sentinel 类似的限流逻辑,需考虑优先级;
    • Sentinel 通常会在网关流程中插入专门的过滤器来处理流量控制。
  3. 动静分离

    • 如果需要对静态资源进行特殊路由或限流,可以在 gateway 中单独定义一个 route(匹配 Path=/static/**),或让静态资源由 Nginx/CDN 承担,gateway 仅处理微服务请求。
  4. 测试与调试

    • 使用工具(如 JMeter、Postman、wrk)对网关进行并发访问,观察是否触发限流或熔断;
    • 查看 Sentinel Dashboard 中的网关流控数据,看“通过 / 拒绝”统计是否符合预期。
  5. 灰度发布

    • 如果需要灰度流量控制,可以结合 Sentinel 的 API、metadata 区分版本,或使用 Spring Cloud Gateway 的路由策略对不同用户或流量标签进行筛选。

八、总结

  • Spring Cloud Gateway 自带灵活的路由和负载均衡能力,结合 Sentinel 的流量控制、熔断降级,实现了网关层面的“拦截保护”,保护下游微服务的稳定性。
  • 常见集成步骤:
    1. 引入 spring-cloud-starter-gatewayspring-cloud-starter-alibaba-sentinel
    2. 配置 gateway 路由(可结合注册中心使用 lb://
    3. 在代码或配置中心中声明 GatewayFlowRuleDegradeRule 等限流 / 熔断规则
    4. 可通过 GatewayCallbackManager 自定义被限流后的响应
    5. 结合 Dashboard 做监控、调试
  • 同时也可在网关层进行更多操作(安全鉴权、协议转换、灰度发布、跨域处理等)。

希望上述内容能帮助你快速上手 Spring Cloud Gateway + Sentinel 的组合。如果有更复杂的场景需求(如动态路由、灰度流控、全局异常捕获等),可以在此基础上加以扩展和深度实践。祝你开发顺利!

;