本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
- 魔都架构师 | 全网30W技术追随者
- 大厂分布式系统/数据中台实战专家
- 主导交易系统百万级流量调优 & 车联网平台架构
- 🧠 AIGC应用开发先行者 | 区块链落地实践者
- 以技术驱动创新,我们的征途是改变世界!
- 实战干货:编程严选网
Spring Cloud Gateway 支持多种路由模式,主要通过配置不同的 RouteLocator
或使用配置文件(如 application.yml
或 application.properties
)来定义。
Spring Cloud Gateway 在 Spring WebFlux 的 HandlerMapping
基础设施中匹配路由。它内置了许多路由谓词工厂,这些谓词根据 HTTP 请求的不同属性进行匹配。你可以通过逻辑 and
组合多个谓词来实现更复杂的匹配逻辑。
1 Path 路由谓词工厂
Path
谓词工厂接收路径模式列表和一个可选参数 matchTrailingSlash
(默认为 true
)。示例:
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
该路由匹配如 /red/1
、/red/1/
、/red/blue
或 /blue/green
的路径。
如果 matchTrailingSlash
设置为 false
,则 /red/1/
不会匹配。
若设置了 spring.webflux.base-path
,其值会自动添加到路径前。例如设置为 /app
,匹配路径将为 /app/red/{segment}
。
提取的 URI 模板变量(如 segment
)可通过以下方式获取:
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
根据请求的路径进行路由。例如,将所有以 /api/**
开头的请求路由到某个服务。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://example.com
predicates:
- Path=/api/**
2 Host 路由谓词工厂
Host
谓词工厂接收一个参数:主机名的模式列表(使用 Ant 风格语法,.
作为分隔符)。示例:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
该路由匹配如 www.somehost.org
、beta.somehost.org
或 www.anotherhost.org
的请求。
如果使用 URI 模板变量(如 {sub}.myhost.org
),匹配到的值会被放入 ServerWebExchange.getAttributes()
中,并可供 GatewayFilter
工厂 使用。
3 Query 路由谓词工厂
Query
谓词工厂接收一个必需参数 param
,及可选正则表达式 regexp
。
示例:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
该路由匹配 red
查询参数,且值匹配正则 gree.
,如 green
和 greet
。
4 Header 路由谓词工厂
Header
谓词工厂接收两个参数:header
名称和正则表达式。用于匹配指定请求头名称和值的请求。
示例:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
该路由匹配带有 X-Request-Id
请求头,且其值为数字(\d+
)的请求。基于头的路由
根据请求的头信息进行路由。例如,将所有包含 X-Request-Id=123
的请求路由到某个服务。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.com
predicates:
- Header=X-Request-Id,123
5 基于Cookie的路由
Cookie
谓词工厂接收两个参数:cookie 的 name
和一个正则表达式 regexp
(Java 格式)。用于匹配指定名称且值符合正则的 Cookie。
根据请求的Cookie进行路由。例如,将所有包含 session=123
的Cookie的请求路由到某个服务。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.com
predicates:
- Cookie=session,123
6 Method 路由谓词工厂
Method
谓词工厂接收一个或多个 HTTP 方法作为参数。示例:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
该路由匹配请求方法为 GET
或 POST
的请求。
7 After 路由谓词工厂
After
谓词工厂接收一个参数:datetime
(类型为 Java 的 ZonedDateTime
)。该谓词用于匹配发生在指定时间之后的请求。示例如下:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
该路由将匹配在 2017 年 1 月 20 日 17:42(美国丹佛时间)之后发出的所有请求。
8 Before 路由谓词工厂
Before
谓词工厂也接收一个 datetime
参数,用于匹配指定时间之前的请求。示例:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
该路由匹配在 2017 年 1 月 20 日 17:42(丹佛时间)之前发出的请求。
9 Between 路由谓词工厂
Between
谓词工厂接收两个参数:datetime1
和 datetime2
(都是 Java 的 ZonedDateTime
对象)。该谓词匹配发生在 datetime1
和 datetime2
之间的请求。datetime2
必须晚于 datetime1
。示例:
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
该路由匹配在 2017 年 1 月 20 日 17:42 到 2017 年 1 月 21 日 17:42(丹佛时间)之间的请求,常用于维护时间段控制。
10 RemoteAddr 路由谓词工厂
RemoteAddr
谓词工厂接收一个 CIDR 格式的地址列表(IPv4 或 IPv6)。示例:
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
该路由匹配远程地址为 192.168.1.10
的请求。
修改远程地址的解析方式
默认情况下,该谓词使用请求中的远程地址。如果网关处于代理之后,这可能不是实际客户端 IP。
可以通过设置自定义 RemoteAddressResolver
来改变解析方式。Spring Cloud Gateway 提供了一个基于 X-Forwarded-For 头的实现:XForwardedRemoteAddressResolver
。
该类提供两个静态方法:
trustAll
:使用X-Forwarded-For
中第一个 IP 地址,容易被伪造。maxTrustedIndex
:根据可信代理层数确定可信 IP 的索引。
示例头部:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
不同 maxTrustedIndex
值对应的解析结果如下:
maxTrustedIndex | 结果 |
---|---|
[Integer.MIN_VALUE , 0] |
初始化时抛出异常 |
1 | 0.0.0.3 |
2 | 0.0.0.2 |
3 | 0.0.0.1 |
[4, Integer.MAX_VALUE ] |
0.0.0.1 |
Java 配置示例:
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("https://downstream1")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("https://downstream2")
)
11 Weight 路由谓词工厂
Weight
谓词工厂接收两个参数:group
和 weight
(整数),权重在组内计算。示例:
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
大约 80% 的请求会被转发到 weighthigh.org
,20% 转发到 weightlow.org
。
12 XForwardedRemoteAddr 路由谓词工厂
该谓词工厂接收 CIDR 格式地址列表,用于根据 X-Forwarded-For
头过滤请求。常用于部署在反向代理之后的场景,只允许来自可信 IP 的请求通过。
示例:
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
当请求头中的 X-Forwarded-For
包含如 192.168.1.10
的地址时,该路由匹配成功。
13 组合路由
可以组合多个谓词(Predicates)来实现更复杂的路由逻辑。例如,将所有来自 example.com
且路径以 /api/**
开头的请求路由到某个服务。
spring:
cloud:
gateway:
routes:
- id: combined_route
uri: http://example.com
predicates:
- Host=example.com
- Path=/api/**
这些路由模式可以根据实际需求进行灵活组合,以满足不同的业务场景。Spring Cloud Gateway 提供了强大的路由功能,使得微服务架构中的请求路由更加灵活和可配置。
- Path=/api/**
这些路由模式可以根据实际需求灵活组合,以适应各种业务场景。Spring Cloud Gateway 提供了强大的路由功能,使微服务架构中的请求路由变得更加灵活和可配置。
本文由博客一文多发平台 OpenWrite 发布!