Spring Cloud Gateway配置
你好呀,我的老朋友!我是老寇,欢迎来到老寇IoT云平台!
# 介绍
Spring Cloud Gateway官方地址 (opens new window)
提供了一个建立在 Spring 生态系统之上的 API 网关,包括:Spring Framework 7、Spring Boot 4 和 Project Reactor。 Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域关注点,例如:安全性,监控/指标、限流、路由等等。
注意
- 不启用网关,请设置
spring.cloud.gateway.enabled=false - Spring Cloud Gateway需要运行在由Spring Webflux(响应式)提供的Netty容器,不适用于传统的Servlet容器或作为WAR构建
核心概念
- Route (路由):网关的基本构建块。它由一个 ID、一个目标 URI、一组断言 (Predicates) 和一组过滤器 (Filters) 组成,如果满足Predicate,则匹配路由。
- Predicate (断言):断言,这是jdk8 断言函数,输入类型是
Spring Framework ServerWebExchange,用于匹配 HTTP 请求的条件。如果请求匹配断言,则路由会被执行,例如请求头或参数。 - Filter (过滤器):是使用特定工厂构造的
GatewayFilter实例,分为两种类型,分别是Gateway Filter(某个路由过滤器)和Global Filter(全局过滤器),在请求被路由到目标服务之前或之后对请求或响应进行修改。
流程图
# 配置方式
# 1. 简单路由配置
最基本的路由配置包括一个 ID、一个目标 URI 和至少一个断言。
配置示例 (application.yml)
spring:
cloud:
gateway:
routes:
- id: example_route
uri: http://localhost:8081 # 目标服务地址
predicates:
- Path=/example/** # 当请求路径匹配 /example/** 时,路由到目标服务
说明
id: 路由的唯一标识符。uri: 目标服务的 URI。可以是http://、https://、lb://(用于负载均衡) 等。predicates: 断言列表。这里使用了Path断言,表示当请求路径符合/example/**时,该路由生效。
# 2. 常用断言 (Predicates)
Spring Cloud Gateway 提供了多种内置断言,用于匹配不同的请求条件。
| 断言名称 | 描述 | 示例 |
|---|---|---|
Path | 根据请求路径匹配 | Path=/foo/{segment} |
Host | 根据请求的 Host 头匹配 | Host=**.somehost.org,**.anotherhost.org |
Method | 根据请求的 HTTP 方法匹配 | Method=GET,POST |
Header | 根据请求头匹配 | Header=X-Request-Id, \d+ |
Query | 根据请求参数匹配 | Query=baz 或 Query=foo,bar |
Cookie | 根据 Cookie 匹配 | Cookie=baz,foo |
After | 在指定时间之后匹配 | After=2023-01-01T12:00:00+08:00[Asia/Shanghai] |
Before | 在指定时间之前匹配 | Before=2023-01-01T12:00:00+08:00[Asia/Shanghai] |
Between | 在两个指定时间之间匹配 | Between=2023-01-01T12:00:00+08:00[Asia/Shanghai],2023-01-31T12:00:00+08:00[Asia/Shanghai] |
RemoteAddr | 根据远程 IP 地址匹配 | RemoteAddr=192.168.1.1/24 |
Weight | 用于 A/B 测试或灰度发布,根据权重进行路由 | Weight=group1, 80 |
配置示例 (多个断言)
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: lb://user-service # 使用负载均衡到名为 user-service 的服务
predicates:
- Path=/users/**
- Method=GET,POST
- Header=X-Version, v1 # 请求头 X-Version 必须为 v1
说明
lb://user-service:lb前缀表示使用 Spring Cloud LoadBalancer 进行负载均衡,user-service是注册中心中的服务名。- 当一个路由配置了多个断言时,只有当所有断言都匹配成功时,该路由才会生效。
# 3. 常用过滤器 (Filters)
过滤器允许您在请求被路由到目标服务之前或之后修改请求和响应。
| 过滤器名称 | 描述 | 示例 |
|---|---|---|
AddRequestHeader | 添加请求头 | AddRequestHeader=X-Request-Foo, Bar |
AddResponseHeader | 添加响应头 | AddResponseHeader=X-Response-Foo, Bar |
RemoveRequestHeader | 移除请求头 | RemoveRequestHeader=X-Request-Foo |
RemoveResponseHeader | 移除响应头 | RemoveResponseHeader=X-Response-Foo |
RewritePath | 重写请求路径 | RewritePath=/foo/(?.*), /${remaining} |
PrefixPath | 给请求路径添加前缀 | PrefixPath=/my-prefix |
StripPrefix | 移除请求路径中的前缀 | StripPrefix=1 (移除一个路径段) |
Retry | 重试机制 | Retry=3 (重试 3 次) |
CircuitBreaker | 熔断器 (与 Resilience4j 或 Hystrix 集成) | CircuitBreaker=myCircuitBreaker |
RequestRateLimiter | 请求速率限制 (基于 Redis 或其他) | RequestRateLimiter=#{#user.name}, 1, 1, 10 (用户名为 key,每秒 1 个请求,突发 1 个,令牌桶容量 10) |
RedirectTo | 重定向 | RedirectTo=302, https://example.com |
配置示例 (过滤器)
spring:
cloud:
gateway:
routes:
- id: api_route
uri: http://localhost:8082
predicates:
- Path=/api/**
filters:
- StripPrefix=1 # 移除 /api 前缀,例如 /api/v1/users -> /v1/users
- AddRequestHeader=X-Custom-Header, Gateway-Request # 添加自定义请求头
- RequestRateLimiter: # 速率限制
key-resolver: '#{@ipAddressKeyResolver}' # 使用 SpEL 表达式定义限流 key
redis-rate-limiter.replenishRate: 1 # 每秒允许多少个请求
redis-rate-limiter.burstCapacity: 2 # 令牌桶的容量
redis-rate-limiter.requestedTokens: 1 # 每次请求消耗的令牌数
说明
StripPrefix=1: 移除请求路径的第一个路径段。AddRequestHeader: 添加一个名为X-Custom-Header,值为Gateway-Request的请求头。RequestRateLimiter: 配置请求速率限制。key-resolver: 定义用于限流的 key。这里使用了@ipAddressKeyResolver,需要您在 Spring 容器中定义一个KeyResolverBean。redis-rate-limiter.replenishRate: 令牌桶每秒填充的平均速率。redis-rate-limiter.burstCapacity: 令牌桶的容量,允许的突发请求数。redis-rate-limiter.requestedTokens: 每次请求消耗的令牌数。
# 4. 全局过滤器 (Global Filters)
全局过滤器应用于所有路由。它们通过实现 GlobalFilter 接口或使用 spring.cloud.gateway.default-filters 配置。
配置示例 (默认过滤器)
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Global-Header, Global-Value # 为所有响应添加一个全局头
- PrefixPath=/global-prefix # 为所有请求路径添加前缀
routes:
- id: service_a
uri: http://localhost:8083
predicates:
- Path=/serviceA/**
- id: service_b
uri: http://localhost:8084
predicates:
- Path=/serviceB/**
说明
default-filters: 定义的过滤器将应用于所有路由。
# 5. 跨域配置 (CORS)
Spring Cloud Gateway 支持配置 CORS。
配置示例
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 匹配所有路径
allowedOrigins: "http://localhost:8080" # 允许的来源
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders: "*" # 允许所有请求头
allowCredentials: true # 允许发送 Cookie
maxAge: 3600 # 预检请求的缓存时间
说明
globalcors: 全局 CORS 配置。cors-configurations: 具体的 CORS 规则。[/**]: 匹配所有路径。allowedOrigins: 允许的源。allowedMethods: 允许的 HTTP 方法。allowedHeaders: 允许的请求头。allowCredentials: 是否允许发送凭证(如 Cookie)。maxAge: 预检请求的有效期。
# 6. 错误处理
Spring Cloud Gateway 提供了默认的错误处理机制,也可以自定义。
自定义错误页面 (示例)
通常通过实现 ErrorWebExceptionHandler 接口来定制错误处理逻辑。
// 示例代码,非配置
@Component
@Order(-1) // 优先级要高于 Gateway 的默认错误处理器
public class CustomErrorWebExceptionHandler implements ErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
// 自定义错误处理逻辑,例如返回 JSON 格式的错误信息
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String errorMsg = "Gateway Error: " + ex.getMessage();
DataBuffer buffer = response.bufferFactory().wrap(errorMsg.getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(buffer));
}
}
# 7. 总结
Spring Cloud Gateway 是一个功能强大且灵活的 API 网关,通过其丰富的断言和过滤器,可以实现复杂的路由逻辑、请求/响应转换、安全控制、流量管理等功能。理解其核心概念和配置方式是构建健壮微服务架构的关键。
我是老寇,我们下次再见啦!
上次更新: 2/11/2026, 8:53:44 PM