Spring Cloud Gateway 如何集成 Sentinel 来实现限流、熔断、动态路由以及负载均衡、路径匹配等核心功能的综合指南。该教程会从依赖引入、网关配置、Sentinel 规则定义到代码示例进行逐步说明。
一、Spring Cloud Gateway 与 Sentinel 概述
- Spring Cloud Gateway:基于 Spring WebFlux 的网关解决方案,能够为微服务提供统一的路由、限流、熔断、安全、监控等功能。
- Sentinel:阿里开源的一款高可用防护框架,提供灵活的流量控制、熔断降级、系统负载保护等功能,可与 Spring Cloud Gateway 深度整合,实现网关层的统一限流和熔断。
1.1 主要功能
- 动态路由:可通过配置或代码动态添加、删除、修改路由规则。
- 负载均衡:使用
lb://service-name
URI 与 Spring Cloud LoadBalancer 集成,实现服务名到实例列表的自动发现与轮询。 - 路径匹配:基于
Path
、Host
、Header
、Query
等多种 Predicates 进行灵活路由匹配。 - 限流与熔断:通过 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>
添加 Gateway 与 Sentinel 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
说明:
uri: lb://...
表示启用负载均衡,由 Spring Cloud LoadBalancer 或 Ribbon(老版本)对后端实例进行轮询。StripPrefix=1
用于删除路由转发时的第一级路径,如请求/inventory/list
会被转发到下游服务/list
。discovery.locator.enabled=true
表示自动根据注册中心(如 Nacos、Eureka 等)去生成路由规则,无需手动在配置文件中逐一写死。
三、集成 Sentinel 实现限流和熔断
3.1 网关层限流基本原理
- Sentinel 提供了一个 Spring Cloud Gateway Starter 模块(已内置于
spring-cloud-starter-alibaba-sentinel
中),会自动注入GatewayFlowRuleManager
、GatewayCallbackManager
等组件。 - 通过为网关路由或自定义资源指定限流规则,可以在网关层面对某条路由(或某个路径)进行 QPS / 并发数 限流、或在后端响应超时时触发熔断降级。
3.2 Gateway 规则模型
Sentinel 为 Gateway 定义了以下维度的限流规则:
- Route ID:按网关
Route
进行限流。 - URL Path:按具体路径匹配限流。
- 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 的自定义限流提示。
高级用法:
- 指定限流维度(Path、Method、Host 等)。
- 配合 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
:
- Predicates:用来匹配请求的条件,如
Path
,Host
,Method
,Header
等。 - 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 配置方式
- 静态配置:在
application.yml
中写死路由规则。 - 基于服务发现:
spring.cloud.gateway.discovery.locator.enabled=true
,自动为每个注册中心中的服务创建路由。 - 数据库 / 配置中心:将路由信息存在数据库或 Nacos Config / Apollo 中,动态刷新网关配置。
- 编程式管理路由:使用
RouteDefinitionWriter
或RouteDefinitionRepository
动态增删改查路由。
5.2 Sentinel + 动态路由
当我们修改或新增网关路由时,也可以动态更新对应的 Sentinel GatewayFlowRule 或 DegradeRule 规则,以便对新路由生效。常见做法:
- 将 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 的限流或熔断逻辑。
七、常见问题与建议
-
Sentinel Dashboard 无法显示网关信息
- 确认
spring.cloud.sentinel.transport.dashboard=ip:port
正确且能连通。 - 检查日志中是否有
Sentinel Default Transport Exception
等错误。 - 需要在同一个版本兼容的情况下使用 Spring Cloud Alibaba + Sentinel Dashboard。
- 确认
-
网关全局过滤器与 Sentinel 冲突
- Spring Cloud Gateway 全局过滤器通常在
GlobalFilter
或Filter
中执行,如果有与 Sentinel 类似的限流逻辑,需考虑优先级; - Sentinel 通常会在网关流程中插入专门的过滤器来处理流量控制。
- Spring Cloud Gateway 全局过滤器通常在
-
动静分离
- 如果需要对静态资源进行特殊路由或限流,可以在 gateway 中单独定义一个 route(匹配 Path=/static/**),或让静态资源由 Nginx/CDN 承担,gateway 仅处理微服务请求。
-
测试与调试
- 使用工具(如 JMeter、Postman、wrk)对网关进行并发访问,观察是否触发限流或熔断;
- 查看 Sentinel Dashboard 中的网关流控数据,看“通过 / 拒绝”统计是否符合预期。
-
灰度发布
- 如果需要灰度流量控制,可以结合 Sentinel 的 API、metadata 区分版本,或使用 Spring Cloud Gateway 的路由策略对不同用户或流量标签进行筛选。
八、总结
- Spring Cloud Gateway 自带灵活的路由和负载均衡能力,结合 Sentinel 的流量控制、熔断降级,实现了网关层面的“拦截保护”,保护下游微服务的稳定性。
- 常见集成步骤:
- 引入 spring-cloud-starter-gateway 与 spring-cloud-starter-alibaba-sentinel
- 配置
gateway
路由(可结合注册中心使用lb://
) - 在代码或配置中心中声明 GatewayFlowRule、DegradeRule 等限流 / 熔断规则
- 可通过 GatewayCallbackManager 自定义被限流后的响应
- 结合 Dashboard 做监控、调试
- 同时也可在网关层进行更多操作(安全鉴权、协议转换、灰度发布、跨域处理等)。
希望上述内容能帮助你快速上手 Spring Cloud Gateway + Sentinel 的组合。如果有更复杂的场景需求(如动态路由、灰度流控、全局异常捕获等),可以在此基础上加以扩展和深度实践。祝你开发顺利!