1. 如何包含 Spring Cloud Gateway
要将 Spring Cloud Gateway 包含在您的项目中,请使用带有 org.springframework.cloud
group ID 和 spring-cloud-starter-gateway
artifact ID 的启动器。有关如何使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参见 Spring Cloud 项目页面。
如果您包含了启动器但不希望启用网关,可以设置 spring.cloud.gateway.enabled=false
。
2. 术语表
-
路由 (Route): 网关的基本构建块。它由 ID、目标 URI、断言集合和过滤器集合定义。如果聚合断言为真,则匹配该路由。
-
断言 (Predicate): 这是一个 Java 8 函数式断言。输入类型是 Spring Framework 的
ServerWebExchange
。它允许您匹配来自 HTTP 请求的任何内容,如头或参数。 -
过滤器 (Filter): 这些是使用特定工厂构建的
GatewayFilter
实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。
3. 如何工作
以下图表提供了 Spring Cloud Gateway 工作方式的高级概述:
客户端向 Spring Cloud Gateway 发送请求。如果 Gateway Handler Mapping 确定请求匹配某个路由,则将其发送到 Gateway Web Handler。这个处理器会将请求运行通过特定于请求的过滤器链。
过滤器由虚线分隔的原因是因为过滤器可以在发送代理请求之前和之后运行逻辑。首先执行所有“预”过滤器逻辑。然后发起代理请求。代理请求完成后,运行“后”过滤器逻辑。
在路由中定义的 URIs,如果没有指定端口,则 HTTP 和 HTTPS URIs 分别默认使用端口 80 和 443。
4. 配置路由断言工厂和网关过滤器工厂
有两种配置断言和过滤器的方法:快捷方式和完全展开的参数。下面的大多数示例使用快捷方式。
名称和参数名称在每个部分的前两句话中以 代码
形式列出。参数通常按快捷配置所需的顺序列出。
4.1. 快捷配置
快捷配置由过滤器名称、等号 (=
) 和由逗号 (,
) 分隔的参数值组成。
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
前面的示例定义了 Cookie
路由断言工厂,它有两个参数,cookie 名称 mycookie
和要匹配的值 mycookievalue
。
4.2. 完全展开的参数
完全展开的参数看起来更像是标准 yaml 配置,具有名称/值对。通常,会有一个 name
键和一个 args
键。args
键是一个键值对映射,用于配置断言或过滤器。
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
这是前面 Cookie
断言快捷配置的完整配置。
5. 路由断言工厂
Spring Cloud Gateway 作为 Spring WebFlux HandlerMapping
基础设施的一部分匹配路由。Spring Cloud Gateway 包括许多内置的路由断言工厂。所有这些断言都匹配 HTTP 请求的不同属性。您可以使用逻辑 and
语句组合多个路由断言工厂。
5.1. After 路由断言工厂
After
路由断言工厂接受一个参数,datetime
(这是一个 Java ZonedDateTime
)。这个断言匹配指定 datetime 之后发生的请求。
以下示例配置了一个 after 路由断言:
application.yml 示例:
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 Mountain Time (Denver) 之后发起的请求。
5.2. Before 路由断言工厂
Before
路由断言工厂接受一个参数,datetime
(这是一个 Java ZonedDateTime
)。这个断言匹配指定 datetime
之前发生的请求。
以下示例配置了一个 before 路由断言:
application.yml 示例:
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 Mountain Time (Denver) 之前发起的请求。
5.3. Between 路由断言工厂
Between
路由断言工厂接受两个参数,datetime1
和 datetime2
,它们是 Java ZonedDateTime
对象。这个断言匹配 datetime1
之后和 datetime2
之前发生的请求。datetime2
参数必须在 datetime1
之后。
以下示例配置了一个 between 路由断言:
application.yml 示例:
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 Mountain Time (Denver) 之后和 2017 年 1 月 21 日 17:42 Mountain Time (Denver) 之前发起的请求。这可以用于维护窗口。
5.4. Cookie 路由断言工厂
Cookie
路由断言工厂接受两个参数,cookie 的 name
和一个 regexp
(这是一个 Java 正则表达式)。这个断言匹配具有给定名称且其值与正则表达式匹配的 cookie。
以下示例配置了一个 cookie 路由断言工厂:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
这个路由匹配请求中有一个名为 chocolate
的 cookie,其值匹配 ch.p
正则表达式。
5.5 Header路由断言工厂
Header
路由断言工厂接受两个参数,header
和一个 regexp
(这是一个 Java 正则表达式)。这个断言匹配具有给定名称且其值与正则表达式匹配的 header。
以下示例配置了一个 header 路由断言:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
这个路由匹配如果请求具有一个名为 X-Request-Id
的 header,其值匹配 \d+
正则表达式(即,它有一个或多个数字的值)。
5.6. Host 路由断言工厂
Host
路由断言工厂接受一个参数:一个主机名 patterns
列表。模式是使用 .
作为分隔符的 Ant 风格模式。
这个断言匹配匹配模式的 Host
头。
以下示例配置了一个 host 路由断言:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
URI 模板变量(例如 {sub}.myhost.org
)也受到支持。
这个路由匹配如果请求具有 Host
头的值为 www.somehost.org
或 beta.somehost.org
或 www.anotherhost.org
。
这个断言还提取 URI 模板变量(如前面的示例中定义的 sub
)作为名称和值的映射,并将其放置在 ServerWebExchange.getAttributes()
中,使用 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键。然后,这些值可供 GatewayFilter
工厂使用。
5.7. Method 路由断言工厂
Method
路由断言工厂接受一个 methods
参数,这是一或多个参数:要匹配的 HTTP 方法。
以下示例配置了一个方法路由断言:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
这个路由匹配如果请求方法是 GET
或 POST
。
5.8. Path 路由断言工厂
Path
路由断言工厂接受两个参数:Spring PathMatcher
patterns
的列表和可选的标志 matchTrailingSlash
(默认为 true
)。
以下示例配置了一个路径路由断言:
application.yml 示例:
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/
将不匹配。
这个断言还提取 URI 模板变量(如前面的示例中定义的 segment
)作为名称和值的映射,并将其放置在 ServerWebExchange.getAttributes()
中,使用 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键。然后,这些值可供 GatewayFilter
工厂使用。
一个实用方法(称为 get
)可用于更方便地访问这些变量。
以下示例展示了如何使用 get
方法:
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
5.9. Query 路由断言工厂
Query
路由断言工厂接受两个参数:一个必需的 param
和一个可选的 regexp
(这是一个 Java 正则表达式)。
以下示例配置了一个查询路由断言:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
如果请求包含一个 green
查询参数,则前面的路由匹配。
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
如果请求包含一个 red
查询参数,其值匹配 gree.
正则表达式,那么前面的路由匹配,因此 green
和 greet
将匹配。
5.10. RemoteAddr 路由断言工厂
RemoteAddr
路由断言工厂接受一个列表(最小大小为 1)的 sources
,这些是 CIDR 表示法(IPv4 或 IPv6)字符串,例如 192.168.0.1/16
(其中 192.168.0.1
是 IP 地址,16
是子网掩码)。
以下示例配置了一个 RemoteAddr 路由断言:
application.yml 示例:
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址是 192.168.1.10
,则此路由匹配。
5.10.1 修改远程地址解析方式
默认情况下,RemoteAddr 路由断言工厂使用传入请求的远程地址。如果 Spring Cloud Gateway 位于代理层后面,这可能不匹配实际客户端 IP 地址。
您可以通过设置自定义 RemoteAddressResolver
来自定义远程地址的解析方式。Spring Cloud Gateway 附带了一个基于 X-Forwarded-For
头的非默认远程地址解析器 XForwardedRemoteAddressResolver
。
XForwardedRemoteAddressResolver
有两个静态构造方法,它们采用不同的安全方法:
-
XForwardedRemoteAddressResolver::trustAll
返回一个RemoteAddressResolver
,它总是采用X-Forwarded-For
头中的第一个 IP 地址。这种方法容易受到欺骗,因为恶意客户端可以为X-Forwarded-For
设置初始值,解析器将接受该值。 -
XForwardedRemoteAddressResolver::maxTrustedIndex
采用一个索引,该索引与 Spring Cloud Gateway 前面运行的受信任基础设施的数量相关联。如果 Spring Cloud Gateway 只能通过 HAProxy 访问,则应使用值 1。如果需要两个受信任基础设施跳数才能访问 Spring Cloud Gateway,则应使用值 2。
考虑以下头值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
以下 maxTrustedIndex
值产生以下远程地址:
maxTrustedIndex | 结果 |
---|---|
[Integer.MIN_VALUE , 0] | (无效,在初始化期间抛出 IllegalArgumentException ) |
1 | 0.0.0.3 |
2 | 0.0.0.2 |
3 | 0.0.0.1 |
[4, Integer.MAX_VALUE ] | 0.0.0.1 |
以下示例展示了如何使用 Java 实现相同的配置:
示例 11. GatewayConfig.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis")))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint"))
.uri("lb://backing-service:8088"))
.build();
}
5.11. Weight 路由断言工厂
Weight
路由断言工厂接受两个参数:group
和 weight
(一个整数)。权重是按组计算的。
以下示例配置了一个权重路由断言:
application.yml 示例:
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
5.12. XForwarded Remote Addr 路由断言工厂
XForwarded Remote Addr
路由断言工厂接受一个列表(最小大小为 1)的 sources
,这些是 CIDR 表示法(IPv4 或 IPv6)字符串,例如 192.168.0.1/16
(其中 192.168.0.1
是 IP 地址,16
是子网掩码)。
这个路由断言允许基于 X-Forwarded-For
HTTP 头过滤请求。
这可以与反向代理如负载均衡器或 Web 应用程序防火墙一起使用,其中请求只有在来自这些反向代理使用的受信任 IP 地址列表时才被允许。
以下示例配置了一个 XForwardedRemoteAddr 路由断言:
application.yml 示例:
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
,则此路由匹配。
好的,我将从您提供的链接开始,包括标题在内的完整翻译如下:
6. GatewayFilter 工厂
路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器限定在特定路由的范围内。Spring Cloud Gateway 包括许多内置的 GatewayFilter 工厂。
6.1. AddRequestHeader
AddRequestHeader
GatewayFilter 工厂接受 name
和 value
参数。
以下示例配置了一个 AddRequestHeader
GatewayFilter:
示例 14. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
这个配置为所有匹配的请求向下游请求的头中添加了 X-Request-red:blue
头。
AddRequestHeader
能够识别用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时展开。以下示例配置了一个使用变量的 AddRequestHeader
GatewayFilter:
示例 15. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
6.2. AddRequestHeadersIfNotPresent
AddRequestHeadersIfNotPresent
GatewayFilter 工厂接受由冒号分隔的 name
和 value
对集合。
以下示例配置了一个 AddRequestHeadersIfNotPresent
GatewayFilter:
示例 16. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_headers_route
uri: https://example.org
filters:
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
这个配置为所有匹配的请求向下游请求的头中添加了两个头 X-Request-Color-1:blue
和 X-Request-Color-2:green
。这类似于 AddRequestHeader
的工作方式,但与 AddRequestHeader
不同的是,只有在头不已经存在的情况下才会添加它们。否则,将发送客户端请求中的原始值。
此外,要设置多值头,可以使用头名称多次,如 AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green
。
AddRequestHeadersIfNotPresent
还支持 URI 变量,这些变量用于匹配路径或主机。URI 变量可以在值中使用,并在运行时展开。以下示例配置了一个使用变量的 AddRequestHeadersIfNotPresent
GatewayFilter:
示例 17. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
6.3. AddRequestParameter
AddRequestParameter
GatewayFilter 工厂接受 name
和 value
参数。
以下示例配置了一个 AddRequestParameter
GatewayFilter:
示例 18. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这个配置将为所有匹配的请求向下游请求的查询字符串中添加 red=blue
。
AddRequestParameter
能够识别用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时展开。以下示例配置了一个使用变量的 AddRequestParameter
GatewayFilter:
示例 19. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
6.4. AddResponseHeader
AddResponseHeader
GatewayFilter 工厂接受 name
和 value
参数。
以下示例配置了一个 AddResponseHeader
GatewayFilter:
示例 20. application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
这个配置为所有匹配的请求向下游响应的头中添加了 X-Response-Red:Blue
头。
AddResponseHeader
能够识别用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时展开。以下示例配置了一个使用变量的 AddResponseHeader
GatewayFilter:
示例 21. application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
6.5. CircuitBreaker
Spring Cloud CircuitBreaker GatewayFilter 工厂使用 Spring Cloud CircuitBreaker API 将网关路由包装在断路器中。Spring Cloud CircuitBreaker 支持多个库,可以与 Spring Cloud Gateway 一起使用。Spring Cloud 支持 Resilience4J 作为开箱即用的解决方案。
要启用 Spring Cloud CircuitBreaker 过滤器,您需要将 spring-cloud-starter-circuitbreaker-reactor-resilience4j
添加到类路径中。
以下示例配置了一个 Spring Cloud CircuitBreaker GatewayFilter
:
示例 22. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参见您使用的底层断路器实现的配置。
- Resilience4J 文档
Spring Cloud CircuitBreaker 过滤器还可以接受一个可选的 fallbackUri
参数。目前,仅支持 forward:
方案的 URI。
如果调用了回退,请求将转发到与 URI 匹配的控制器。
以下示例配置了这样的回退:
示例 23. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
以下列表以 Java 形式完成了相同的操作:
示例 24. Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088"))
.build();
}
这个示例在调用断路器回退时转发到 /inCaseOfFailureUseThis
URI。请注意,此示例还演示了(可选的)Spring Cloud LoadBalancer 负载均衡(由目的 URI 上的 lb
前缀定义)。
断路器还支持 fallbackUri
中的 URI 变量。这允许更复杂的路由选项,例如使用 PathPattern 表达式转发原始主机或 URL 路径的部分。
在下面的示例中,调用 consumingServiceEndpoint/users/1
将被重定向到 inCaseOfFailureUseThis/users/1
。
示例 25. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint/{*segments}
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis/{segments}
主要场景是使用 fallbackUri
来定义网关应用程序内的内部控制器或处理器。然而,您也可以将请求重新路由到外部应用程序中的控制器或处理器,如下所示:
示例 26. application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在这个示例中,网关应用程序中没有 fallback
端点或处理器。但是,在注册到 localhost:9994
的另一个应用程序中有一个。在请求被转发到回退时,Spring Cloud CircuitBreaker Gateway 过滤器还提供了导致它的 Throwable
。它被添加到 ServerWebExchange
作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR
属性,可以在网关应用程序内处理回退时使用。
对于外部控制器/处理器场景,可以在请求头中添加异常详细信息。您可以在 FallbackHeaders GatewayFilter Factory 部分找到更多关于如何执行此操作的信息。
6.5.1. 根据状态码触发断路器
在某些情况下,您可能希望根据路由包装返回的状态码触发断路器。断路器配置对象接受一个状态码列表,如果返回这些状态码,将导致断路器被触发。当设置要触发断路器的状态码时,您可以使用状态码值的整数或 HttpStatus
枚举的字符串表示。
示例 27. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
statusCodes:
- 500
- "NOT_FOUND"
示例 28. Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR")))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088"))
.build();
}
6.6. CacheRequestBody
在某些情况下,需要读取请求体。由于请求体只能读取一次,因此需要缓存请求体。您可以使用 CacheRequestBody
过滤器在将其发送下游之前缓存请求体,并从 exchange
属性中获取体。
以下列表展示了如何缓存请求体 GatewayFilter
:
示例 29. application.yml
spring:
cloud:
gateway:
routes:
- id: cache_request_body_route
uri: lb://downstream
predicates:
- Path=/downstream/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String
CacheRequestBody
提取请求体并将其转换为体类(例如前面示例中定义的 java.lang.String
)。然后,它将体放置在 ServerWebExchange.getAttributes()
可用的属性中,使用 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR
中定义的键。
注意:此过滤器仅适用于 HTTP(包括 HTTPS)请求。
6.7. DedupeResponseHeader
DedupeResponseHeader
GatewayFilter 工厂接受 name
参数和可选的 strategy
参数。name
可以包含一个由空格分隔的头名称列表。
以下示例配置了一个 DedupeResponseHeader
GatewayFilter:
示例 30. application.yml
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
这将在网关 CORS 日志和下游逻辑都添加它们时,移除 Access-Control-Allow-Credentials
和 Access-Control-Allow-Origin
响应头的重复值。
DedupeResponseHeader
过滤器还接受一个可选的 strategy
参数。接受的值为 RETAIN_FIRST
(默认)、RETAIN_LAST
和 RETAIN_UNIQUE
。
6.8. FallbackHeaders
FallbackHeaders
工厂允许您在请求被转发到外部应用程序的 fallbackUri
时,在请求头中添加 Spring Cloud CircuitBreaker 执行异常的详细信息,如下所示:
示例 31. application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
在此示例中,当在运行断路器时发生执行异常,请求将被转发到 localhost:9994
上运行的应用程序的 fallback
端点或处理器。FallbackHeaders
过滤器通过添加异常类型、消息(如果可用的话)以及根原因异常类型和消息的头,来修改该请求。
您可以通过在配置中设置以下参数的值来覆盖头的名称(显示了默认值):
executionExceptionTypeHeaderName
(“Execution-Exception-Type”)executionExceptionMessageHeaderName
(“Execution-Exception-Message”)rootCauseExceptionTypeHeaderName
(“Root-Cause-Exception-Type”)rootCauseExceptionMessageHeaderName
(“Root-Cause-Exception-Message”)
有关断路器和网关的更多信息,请参阅 Spring Cloud CircuitBreaker 工厂部分。
6.9. JsonToGrpc
JSONToGRPCFilter GatewayFilter 工厂将 JSON 负载转换为 gRPC 请求。
该过滤器接受以下参数:
-
protoDescriptor
: Proto 描述文件。该文件可以使用
protoc
生成,并指定--descriptor_set_out
标志:protoc --proto_path=src/main/resources/proto/ \ --descriptor_set_out=src/main/resources/proto/hello.pb \ src/main/resources/proto/hello.proto
-
protoFile
: Proto 定义文件。 -
service
: 处理请求的服务的短名称。 -
method
: 处理请求的服务中的方法名称。注意:不支持流式传输。
application.yml.
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("json-grpc", r -> r.path("/json/hello").filters(f -> {
String protoDescriptor = "file:src/main/proto/hello.pb";
String protoFile = "file:src/main/proto/hello.proto";
String service = "HelloService";
String method = "hello";
return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
}).uri(uri))
.build();
}
spring:
cloud:
gateway:
routes:
- id: json-grpc
uri: https://localhost:6565/testhello
predicates:
- Path=/json/**
filters:
- name: JsonToGrpc
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: HelloService
method: hello
当通过网关向 /json/hello
发出请求时,请求将使用 hello.proto
中提供的定义将请求转换,并发送到 HelloService/hello
,然后将响应转换回 JSON。
默认情况下,它通过使用默认的 TrustManagerFactory
创建一个 NettyChannel
。但是,您可以通过创建一个 GrpcSslConfigurer
类型的 bean 来自定义此 TrustManager
:
@Configuration
public class GRPCLocalConfiguration {
@Bean
public GRPCSSLContext sslContext() {
TrustManager trustManager = trustAllCerts();
return new GRPCSSLContext(trustManager);
}
}
6.10. LocalResponseCache 网关过滤器工厂
此过滤器允许缓存响应体和头,遵循以下规则:
- 它只能缓存无体的 GET 请求。
- 它仅在以下状态码之一的情况下缓存响应:HTTP 200 (OK)、HTTP 206 (Partial Content) 或 HTTP 301 (Moved Permanently)。
- 如果
Cache-Control
头不允许(请求中存在no-store
或响应中存在no-store
或private
),则不缓存响应数据。 - 如果响应已经被缓存,并且新请求在
Cache-Control
头中使用了 no-cache 值,它将返回一个无体的响应,状态码为 304 (Not Modified)。
此过滤器按路由配置本地响应缓存,并且只有在启用了 spring.cloud.gateway.filter.local-response-cache.enabled
属性时才可用。还有一个全局配置的本地响应缓存作为特性提供。
它接受第一个参数以覆盖缓存项过期的时间(以 s
表示秒,m
表示分钟,h
表示小时),第二个参数设置为此路由的缓存最大大小以逐出条目(使用 KB
、MB
或 GB
)。
以下列表显示了如何添加本地响应缓存 GatewayFilter
:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.localResponseCache(Duration.ofMinutes(30), "500MB"))
.uri(uri))
.build();
}
或者这样
application.yaml
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- LocalResponseCache=30m,500MB
注意 |
---|
此过滤器还自动计算 HTTP Cache-Control 头中的 max-age 值。仅当原始响应中存在 max-age 时,才使用 timeToLive 配置参数中设置的秒数重写该值。在连续调用中,该值将根据响应到期前剩余的秒数重新计算。 |
要启用此特性,请将 com.github.ben-manes.caffeine:caffeine 和 spring-boot-starter-cache 添加为项目依赖。 |
如果您的项目创建了自定义 CacheManager beans,它将需要使用 @Primary 标记或使用 @Qualifier 注入。 |
MapRequestHeader
网关过滤器工厂接受 fromHeader
和 toHeader
参数。它创建一个新的命名头 (toHeader
),值从传入的 HTTP 请求的现有命名头 (fromHeader
) 中提取。如果输入头不存在,则过滤器无影响。如果新命名头已经存在,则其值与新值合并。
以下示例配置了一个 MapRequestHeader
:
示例 32. application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
这将向下游请求的头中添加 X-Request-Red:<values>
头,更新自传入 HTTP 请求的 Blue
头的值。
6.12. ModifyRequestBody 网关过滤器工厂
您可以使用 ModifyRequestBody
过滤器在网关将其发送下游之前修改请求体。
注意 : 此过滤器只能通过使用 Java DSL 配置。
以下列表展示了如何修改请求体 GatewayFilter
:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> Mono.just(new Hello(s.toUpperCase()))))
.uri(uri))
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
注意 |
---|
如果请求没有体,RewriteFilter 将传递 null 。应返回 Mono.empty() 以在请求中分配一个缺失的体。 |
6.13. ModifyResponseBody 网关过滤器工厂
您可以使用 ModifyResponseBody
过滤器在将响应发送回客户端之前修改响应体。
注意 :此过滤器只能通过使用 Java DSL 配置。
以下列表展示了如何修改响应体 GatewayFilter
:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
.build();
}
注意 |
---|
如果响应没有体,RewriteFilter 将传递 null 。应返回 Mono.empty() 以在响应中分配一个缺失的体。 |
6.14. PrefixPath 网关过滤器工厂
PrefixPath
网关过滤器工厂接受一个单一的 prefix
参数。
以下示例配置了一个 PrefixPath
网关过滤器:
示例 33. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
这将为所有匹配请求的路径添加前缀 /mypath
。因此,对 /hello
的请求将被发送到 /mypath/hello
。
6.15 PreserveHostHeader网关过滤器工厂
PreserveHostHeader
网关过滤器工厂没有参数。此过滤器设置了一个请求属性,路由过滤器检查该属性以确定是否应发送原始主机头,而不是由 HTTP 客户端确定的主机头。
以下示例配置了一个 PreserveHostHeader
网关过滤器:
示例 34. application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.16. RedirectTo 网关过滤器工厂
RedirectTo
网关过滤器工厂接受三个参数:status
、url
和可选的 includeRequestParams
。
status
参数应该是一个 300 系列的重定向 HTTP 状态码,例如 301。
url
参数应该是一个有效的 URL。这是 Location
头的值。
includeRequestParams
参数指示是否应在 url
上包含请求查询参数。如果未设置,则视为 false
。
对于相对重定向,您应该使用 uri: no://op
作为您的路由定义的 uri。
以下列表配置了一个 RedirectTo
网关过滤器:
示例 35. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送状态 302 和一个 Location:https://acme.org
头来执行重定向。
以下示例配置了一个 RedirectTo
网关过滤器,并将 includeRequestParams
设置为 true
。
application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org, true
当向网关发出带有查询 ?skip=10
的请求时,网关将发送状态 302 和一个 Location:https://acme.org?skip=10
头来执行重定向。
6.17. RemoveJsonAttributesResponseBody 网关过滤器工厂
RemoveJsonAttributesResponseBody
网关过滤器工厂接受一组要搜索的 attribute names
,列表中的最后一个可选参数可以是一个布尔值,指示是否仅在根级别(如果参数配置的末尾没有出现,则为默认值 false
)或递归地(true
)删除这些属性。
它提供了一种方便的方法,通过对 JSON 体内容应用转换来删除其中的属性。
以下示例配置了一个 RemoveJsonAttributesResponseBody
网关过滤器:
示例 36. application.yml
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_route
uri: https://example.org
filters:
- RemoveJsonAttributesResponseBody=id,color
这将在根级别从 JSON 内容体中删除 “id” 和 “color” 属性。
以下示例配置了一个使用可选最后一个参数的 RemoveJsonAttributesResponseBody
网关过滤器:
示例 37. application.yml
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_recursively_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- RemoveJsonAttributesResponseBody=id,color,true
这将从 JSON 内容体的任何级别中删除 “id” 和 “color” 属性。
6.18 RemoveRequestHeader网关过滤器工厂
RemoveRequestHeader
网关过滤器工厂接受一个 name
参数。它是要删除的头的名称。
以下列表配置了一个 RemoveRequestHeader
网关过滤器:
示例 38. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这将在将其发送下游之前删除 X-Request-Foo
头。
6.19. RemoveRequestParameter 网关过滤器工厂
RemoveRequestParameter
网关过滤器工厂接受一个 name
参数。它是要删除的查询参数的名称。
以下示例配置了一个 RemoveRequestParameter
网关过滤器:
示例 39. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
这将在将其发送下游之前删除 red
参数。
6.20 RemoveResponseHeader 网关过滤器工厂
RemoveResponseHeader
网关过滤器工厂接受一个 name
参数。它是要删除的头的名称。
以下列表配置了一个 RemoveResponseHeader
网关过滤器:
示例 40. application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
这将在将响应返回给网关客户端之前从响应中删除 X-Response-Foo
头。
要删除任何类型的敏感头,您应该为可能想要执行此操作的任何路由配置此过滤器。此外,您可以通过使用 spring.cloud.gateway.default-filters
配置此过滤器一次,并将其应用于所有路由。
6.21 RequestHeaderSize 网关过滤器工厂
RequestHeaderSize
网关过滤器工厂接受 maxSize
和 errorHeaderName
参数。
maxSize
参数是请求头允许的最大数据大小(包括键和值)。errorHeaderName
参数设置了包含错误消息的响应头的名称,默认为 “errorMessage”。
以下列表配置了一个 RequestHeaderSize
网关过滤器:
示例 41. application.yml
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B
如果任何请求头的大小超过 1000 字节,这将发送状态 431。
6.22. RequestRateLimiter 网关过滤器工厂
RequestRateLimiter
网关过滤器工厂使用 RateLimiter
实现来确定当前请求是否被允许继续。如果不是,将返回默认状态 HTTP 429 - Too Many Requests
。
此过滤器接受一个可选的 keyResolver
参数和特定于速率限制器的参数(稍后在本节中描述)。
keyResolver
是实现 KeyResolver
接口的一个 bean。在配置中,使用 SpEL 引用 bean 的名称。#{@myKeyResolver}
是一个 SpEL 表达式,引用了一个名为 myKeyResolver
的 bean。
以下列表显示了 KeyResolver
接口:
示例 42. KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver
接口允许插入式策略派生限制请求的键。在未来的里程碑版本中,将有一些 KeyResolver
实现。
默认的 KeyResolver
实现是 PrincipalNameKeyResolver
,它从 ServerWebExchange
中检索 Principal
并调用 Principal.getName()
。
默认情况下,如果 KeyResolver
找不到键,将拒绝请求。您可以通过设置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
(true
或 false
)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
属性来调整这种行为。
RequestRateLimiter
不能用“快捷”符号进行配置。以下示例是无效的:
示例 43. application.properties
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
6.22.1. Redis RateLimiter
Redis 实现基于 Stripe 的工作。它需要使用 spring-boot-starter-data-redis-reactive
Spring Boot 启动器。
redis-rate-limiter.replenishRate
属性定义了每秒允许的请求数(没有任何丢弃的请求)。这是令牌桶填充的速率。
redis-rate-limiter.burstCapacity
属性是用户在一秒钟内允许的最大请求数(没有任何丢弃的请求)。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。
redis-rate-limiter.requestedTokens
属性是每个请求的成本。这是每个请求从桶中取出的令牌数,默认为 1
。
通过设置相同的 replenishRate
和 burstCapacity
值,可以实现稳定速率。通过将 burstCapacity
设置为高于 replenishRate
,可以允许临时突发。在这种情况下,由于 replenishRate
,速率限制器需要在突发之间允许一些时间,因为连续两个突发会导致丢弃请求(HTTP 429 - Too Many Requests
)。
以下列表配置了一个 redis-rate-limiter
:
低于 1 request/s
的速率限制可以通过将 replenishRate
设置为所需的请求数,requestedTokens
设置为秒数的时间跨度,burstCapacity
设置为 replenishRate
和 requestedTokens
的乘积来实现。例如,设置 replenishRate=1
,requestedTokens=60
,burstCapacity=60
将限制为 1 request/min
。
.application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
以下示例在 Java 中配置了一个 KeyResolver
:
示例 44. Config.java
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户的请求速率限制为 10。允许 20 的突发,但接下来一秒钟只有 10 个请求可用。KeyResolver
是一个简单的实现,它获取 user
请求参数。注意:这不是生产推荐的做法。
您还可以定义一个实现 RateLimiter
接口的 bean 作为速率限制器。在配置中,您可以使用 SpEL 引用 bean 的名称。#{@myRateLimiter}
是一个 SpEL 表达式,引用了一个名为 myRateLimiter
的 bean。以下列表定义了一个使用前面定义的 KeyResolver
的速率限制器:
示例 45. application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.23 RewriteLocationResponseHeader网关过滤器工厂
RewriteLocationResponseHeader
网关过滤器工厂修改 Location
响应头的值,通常是为了去掉后端特定的详细信息。它接受 stripVersionMode
、locationHeaderName
、hostValue
和 protocolsRegex
参数。
以下列表配置了一个 RewriteLocationResponseHeader
网关过滤器:
示例 46. application.yml
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters: - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
stripVersionMode
参数有以下可能的值:NEVER_STRIP
、AS_IN_REQUEST
(默认)和 ALWAYS_STRIP
。
NEVER_STRIP
:即使原始请求路径不包含版本,也不会剥离版本。AS_IN_REQUEST
:仅当原始请求路径不包含版本时,才剥离版本。ALWAYS_STRIP
:即使原始请求路径包含版本,也总是剥离版本。
如果提供了 hostValue
参数,则用于替换响应 Location
头中的 host:port
部分。如果没有提供,将使用 Host
请求头的值。
protocolsRegex
参数必须是有效的 regex String
,用于匹配协议名称。如果没有匹配,过滤器将不执行任何操作。默认值为 http|https|ftp|ftps
。
6.24. RewritePath 网关过滤器工厂
RewritePath
网关过滤器工厂接受一个路径 regexp
参数和一个 replacement
参数。它使用 Java 正则表达式灵活地重写请求路径。
以下列表配置了一个 RewritePath
网关过滤器:
示例 47. application.yml
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /${segment}
对于 /red/blue
的请求路径,这在发出下游请求之前将路径设置为 /blue
。请注意,由于 YAML 规范,应将 $
替换为 $\
。
6.25. RewriteRequestParameter 网关过滤器工厂
RewriteRequestParameter
网关过滤器工厂接受一个 name
参数和一个 replacement
参数。它将重写给定 name
的请求参数的值。如果设置了多个具有相同 name
的请求参数,它们将被替换为单个值。如果没有找到请求参数,则不进行任何更改。
以下列表配置了一个 RewriteRequestParameter
网关过滤器:
示例 48. application.yml
spring:
cloud:
gateway:
routes:
- id: rewriterequestparameter_route
uri: https://example.org
predicates:
- Path=/products
filters:
- RewriteRequestParameter=campaign,fall2023
对于 /products?campaign=old
的请求,这将请求参数设置为 campaign=fall2023
。
6.26 RewriteResponseHeader 网关过滤器工厂
RewriteResponseHeader
网关过滤器工厂接受 name
、regexp
和 replacement
参数。它使用 Java 正则表达式灵活地重写响应头的值。
以下示例配置了一个 RewriteResponseHeader
网关过滤器:
示例 49. application.yml
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
对于 /42?user=ford&password=omg!what&flag=true
的头值,在发出下游请求后,它将被设置为 /42?user=ford&password=***&flag=true
。由于 YAML 规范,您必须使用 $\
来表示 $
。
6.27. SaveSession 网关过滤器工厂
SaveSession
网关过滤器工厂在将调用转发到下游之前,强制执行 WebSession::save
操作。当使用像 Spring Session 这样的惰性数据存储时,这特别有用,您需要确保在发出转发调用之前会话状态已被保存。
以下示例配置了一个 SaveSession
网关过滤器:
示例 50. application.yml
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果您将 Spring Security 与 Spring Session 集成,并希望确保安全细节已转发到远程进程,这很关键。
6.28 SecureHeaders网关过滤器工厂
SecureHeaders
网关过滤器工厂根据本博客文章中的建议,向响应添加多个头。
添加了以下头(显示了默认值):
X-Xss-Protection:1 (mode=block)
Strict-Transport-Security (max-age=631138519)
X-Frame-Options (DENY)
X-Content-Type-Options (nosniff)
Referrer-Policy (no-referrer)
Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'
X-Download-Options (noopen)
X-Permitted-Cross-Domain-Policies (none)
要更改默认值,请在 spring.cloud.gateway.filter.secure-headers
命名空间中设置适当的属性。可用以下属性:
xss-protection-header
strict-transport-security
frame-options
content-type-options
referrer-policy
content-security-policy
download-options
permitted-cross-domain-policies
要禁用默认值,请使用逗号分隔的值设置 spring.cloud.gateway.filter.secure-headers.disable
属性。以下示例展示了如何执行此操作:
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
注意 |
---|
使用安全的头的全小写名称来禁用它。 |
6.29. SetPath 网关过滤器工厂
SetPath
网关过滤器工厂接受一个路径 template
参数。它提供了一种简单的方法来通过允许路径的模板化段来操作请求路径。它使用了 Spring Framework 的 URI 模板。允许多个匹配段。
以下示例配置了一个 SetPath
网关过滤器:
示例 51. application.yml
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
对于 /red/blue
的请求路径,这在发出下游请求之前将路径设置为 /blue
。
6.30. SetRequestHeader网关过滤器工厂
SetRequestHeader
网关过滤器工厂接受 name
和 value
参数。
以下列表配置了一个 SetRequestHeader
网关过滤器:
示例 52. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
这个 GatewayFilter
替换(而不是添加)给定名称的所有头。因此,如果下游服务器响应了 X-Request-Red:1234
,它将被替换为 X-Request-Red:Blue
,这就是下游服务将接收到的。
SetRequestHeader
知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时展开。
以下示例配置了一个使用变量的 SetRequestHeader
网关过滤器:
示例 53. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
6.31. SetResponseHeader网关过滤器工厂
SetResponseHeader
网关过滤器工厂接受 name
和 value
参数。
以下列表配置了一个 SetResponseHeader
网关过滤器:
示例 54. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
这个网关过滤器替换(而不是添加)给定名称的所有头。因此,如果下游服务器响应了 X-Response-Red:1234
,它将被替换为 X-Response-Red:Blue
,这就是网关客户端将接收到的。
SetResponseHeader
知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时展开。
以下示例配置了一个使用变量的 SetResponseHeader
网关过滤器:
示例 55. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.32. SetStatus 网关过滤器工厂
SetStatus
网关过滤器工厂接受一个单一的 status
参数。它必须是有效的 Spring HttpStatus
。它可以是整数值 404
或枚举的字符串表示:NOT_FOUND
。
以下列表配置了一个 SetStatus
网关过滤器:
示例 56. application.yml
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=UNAUTHORIZED
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
在任一情况下,响应的 HTTP 状态码将被设置为 401。
您可以配置 SetStatus
网关过滤器,以在响应头中返回代理请求的原始 HTTP 状态码。如果使用以下属性进行配置,则将头添加到响应中:
示例 57. application.yml
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.33. StripPrefix 网关过滤器工厂
StripPrefix
网关过滤器工厂接受一个 parts
参数。parts
参数指示在将请求发送到下游之前,要从请求中剥离的路径部分数。
以下列表配置了一个 StripPrefix
网关过滤器:
示例 58. application.yml
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
当通过网关向 /name/blue/red
发出请求时,向 nameservice
发出的请求看起来像 nameservice/red
。
6.34. Retry 网关过滤器工厂
Retry
网关过滤器工厂支持以下参数:
retries
:应尝试的重试次数。statuses
:应重试的 HTTP 状态码,使用org.springframework.http.HttpStatus
表示。methods
:应重试的 HTTP 方法,使用org.springframework.http.HttpMethod
表示。series
:应重试的状态码系列,使用org.springframework.http.HttpStatus.Series
表示。exceptions
:应重试的抛出异常列表。backoff
:重试的配置指数退避。重试在firstBackoff * (factor ^ n)
的退避间隔后执行,其中n
是迭代次数。如果配置了maxBackoff
,则应用的最大退避限制为maxBackoff
。如果basedOnPreviousValue
为 true,则使用prevBackoff * factor
计算退避。
如果启用了 Retry
过滤器,以下是为其配置的默认值:
retries
:三次series
:5XX 系列methods
:GET 方法exceptions
:IOException
和TimeoutException
backoff
:禁用
以下列表配置了一个 Retry 网关过滤器:
示例 59. application.yml
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
注意 |
---|
使用带有 forward: 前缀 URL 的重试过滤器时,目标端点应小心编写,以便在发生错误时,它不执行任何可能导致向客户端发送并提交响应的操作。例如,如果目标端点是注解控制器,则目标控制器方法不应返回带有错误状态代码的 ResponseEntity 。相反,它应该抛出一个 Exception 或者通过 Mono.error(ex) 返回值发出错误信号,这样重试过滤器就可以配置为通过重试来处理。 |
使用带有任何 HTTP 方法和正文的重试过滤器时,正文将被缓存,网关将受到内存限制。正文被缓存在由 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定义的请求属性中。该对象的类型是 org.springframework.core.io.buffer.DataBuffer 。 |
可以使用单个 status
和 method
添加简化的“快捷”符号。
以下两个示例是等效的:
示例 60. application.yml
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: https://example.org
filters:
- name: Retry
args:
retries: 3
statuses: INTERNAL_SERVER_ERROR
methods: GET
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
- id: retryshortcut_route
uri: https://example.org
filters:
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false
6.35. RequestSize 网关过滤器工厂
当请求大小大于允许的限制时,RequestSize
网关过滤器工厂可以阻止请求到达下游服务。该过滤器接受一个 maxSize
参数。
maxSize
是 DataSize
类型,因此值可以定义为数字,后面是可选的 DataUnit
后缀,如 ‘KB’ 或 ‘MB’。默认值为 ‘B’,表示字节。它是以字节定义的请求的允许大小限制。
以下列表配置了一个 RequestSize
网关过滤器:
示例 61. application.yml
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
RequestSize
网关过滤器工厂将响应状态设置为 413 Payload Too Large
,并在由于大小而拒绝请求时添加一个额外的头 errorMessage
。以下示例显示了这样的 errorMessage
:
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
注意 |
---|
如果在路由定义中未作为过滤器参数提供,则默认请求大小设置为五 MB。 |
6.36. SetRequestHostHeader` 网关过滤器工厂
当需要覆盖主机头时,可以使用 SetRequestHostHeader
网关过滤器工厂将现有主机头替换为指定的值。该过滤器接受一个 host
参数。
以下列表配置了一个 SetRequestHostHeader
网关过滤器:
示例 62. application.yml
spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHostHeader
args:
host: example.org
SetRequestHostHeader
网关过滤器工厂将主机头的值替换为 example.org
。
6.37. TokenRelay 网关过滤器工厂
Token Relay 是指 OAuth2 消费者充当客户端,并将传入的令牌转发到传出的资源请求。消费者可以是纯客户端(如 SSO 应用程序)或资源服务器。
Spring Cloud Gateway 可以将 OAuth2 访问令牌下游转发到它所代理的服务。要将此功能添加到网关,您需要添加 TokenRelayGatewayFilterFactory
,如下所示:
App.java
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay())
.uri("http://localhost:9000"))
.build();
}
或者这样
application.yaml
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay=
它将(除了登录用户并获取令牌之外)将认证令牌下游传递到服务(在本例中为 /resource
)。
要为此启用 Spring Cloud Gateway,请添加以下依赖:
org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的?{githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] 从当前认证的用户中提取访问令牌,并将其放入下游请求的请求头中。
注意 |
---|
如果正确设置了 spring.security.oauth2.client.* 属性,将触发创建 ReactiveClientRegistrationRepository bean,并且仅会创建 TokenRelayGatewayFilterFactory bean 。 |
TokenRelayGatewayFilterFactory 使用的默认实现 ReactiveOAuth2AuthorizedClientService 使用内存数据存储。如果您需要更健壮的解决方案,您需要提供自己的实现 ReactiveOAuth2AuthorizedClientService 。 |
6.38. 默认过滤器
要添加一个过滤器并将其应用于所有路由,您可以使用 spring.cloud.gateway.default-filters
。此属性接受过滤器列表。
以下列表定义了一组默认过滤器:
示例 63. application.yml
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
7. 全局过滤器
GlobalFilter
接口与 GatewayFilter
具有相同的签名。这些是有条件地应用于所有路由的特殊过滤器。
注意 | 注意 | 注意 |
---|---|---|
此接口及其使用方式在将来的里程碑版本中可能会发生变化。 |
7.1. 组合全局过滤器和 GatewayFilter 排序
当请求匹配路由时,过滤 Web 处理器将所有 GlobalFilter
实例和所有特定于路由的 GatewayFilter
实例添加到过滤器链中。这个组合的过滤器链根据 org.springframework.core.Ordered
接口进行排序,您可以通过实现 getOrder()
方法来设置。
由于 Spring Cloud Gateway 在过滤器逻辑执行中区分了“预”和“后”阶段(见工作原理),因此具有最高优先级的过滤器是“预”阶段的第一个和“后”阶段的最后一个。
以下列表配置了过滤器链:
示例 64. ExampleConfiguration.java
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
7.2. 网关指标过滤器
要启用网关指标,请将 spring-boot-starter-actuator
添加为项目依赖。然后,默认情况下,只要 spring.cloud.gateway.metrics.enabled
属性未设置为 false
,网关指标过滤器就会运行。
此过滤器添加了一个名为 spring.cloud.gateway.requests
的计时器指标,带有以下标签:
routeId
:路由 ID。routeUri
:API 路由到的 URI。outcome
:根据 HttpStatus.Series 分类的结果。status
:返回给客户端的 HTTP 请求状态。httpStatusCode
:返回给客户端的 HTTP 状态码。httpMethod
:请求使用的 HTTP 方法。
此外,通过 spring.cloud.gateway.metrics.tags.path.enabled
属性(默认为 false
),您可以激活带有路径标签的额外指标:
path
:请求的路径。
然后,这些指标可以从 /actuator/metrics/spring.cloud.gateway.requests
抓取,并可以轻松地与 Prometheus 集成以创建 Grafana 仪表板。
注意 | 注意 | 注意 |
---|---|---|
要启用 Prometheus 端点,请将 micrometer-registry-prometheus 添加为项目依赖。 |
7.3. 本地响应缓存过滤器
如果启用了相关属性,则 LocalResponseCache
运行:
spring.cloud.gateway.global-filter.local-response-cache.enabled
:为所有路由激活全局缓存。spring.cloud.gateway.filter.local-response-cache.enabled
:激活要在路由级别使用的关联过滤器。
此特性使用 Caffeine 启用本地缓存,用于符合以下条件的所有响应:
- 请求是一个无体的 GET。
- 响应具有以下状态码之一:HTTP 200 (OK)、HTTP 206 (Partial Content) 或 HTTP 301 (Moved Permanently)。
- HTTP
Cache-Control
头允许缓存(即请求中没有no-store
,响应中也没有no-store
或private
)。
它接受两个配置参数:
spring.cloud.gateway.filter.local-response-cache.size
:为此路由设置要逐出条目的最大缓存大小(以 KB、MB 和 GB 为单位)。spring.cloud.gateway.filter.local-response-cache.time-to-live
:设置缓存条目过期的时间(以 s 表示秒,m 表示分钟,h 表示小时)。
如果未配置这些参数,但启用了全局过滤器,默认情况下,它为缓存响应配置了 5 分钟的生存时间。
此过滤器还实现了 HTTP Cache-Control
头中 max-age
值的自动计算。如果在原始响应中存在 max-age
,则该值将使用 timeToLive
配置参数中设置的秒数重写。在后续调用中,该值将根据响应到期前剩余的秒数重新计算。
将 spring.cloud.gateway.global-filter.local-response-cache.enabled
设置为 false
将为所有路由停用本地响应缓存,LocalResponseCache 过滤器允许在路由级别使用此功能。
注意 | 注意 | 注意 |
---|---|---|
要启用此特性,请将 com.github.ben-manes.caffeine:caffeine 和 spring-boot-starter-cache 添加为项目依赖。 | ||
如果您的项目创建了自定义 CacheManager beans,它将需要使用 @Primary 标记或使用 @Qualifier 注入。 |
7.4. 转发路由过滤器
ForwardRoutingFilter
查找 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的 URI。如果 URL 具有 forward
方案(例如 forward:///localendpoint
),它使用 Spring DispatcherHandler
来处理请求。请求 URL 的路径部分被覆盖为转发 URL 中的路径。原始未修改的 URL 被追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。
7.5. Netty 路由过滤器
如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的 URL 具有 http
或 https
方案,则 Netty 路由过滤器运行。它使用 Netty HttpClient
发出下游代理请求。响应被放入 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
交换属性中,供后续过滤器使用。(还有一个实验性的 WebClientHttpRoutingFilter
,执行相同的功能,但不需要 Netty。)
7.6. Netty 写响应过滤器
如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
交换属性中存在 Netty HttpClientResponse
,则 NettyWriteResponseFilter
运行。它在所有其他过滤器完成后运行,并将代理响应写回到网关客户端响应。(还有一个实验性的 WebClientWriteResponseFilter
,执行相同的功能,但不需要 Netty。)
7.7. ReactiveLoadBalancerClientFilter
ReactiveLoadBalancerClientFilter
查找名为 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
的交换属性中的 URI。如果 URL 具有 lb
方案(例如 lb://myservice
),它使用 Spring Cloud ReactorLoadBalancer
将名称(本例中的 myservice
)解析为实际的主机和端口,并替换同一属性中的 URI。原始未修改的 URL 被追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。过滤器还在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性中查看它是否等于 lb
。如果是,则应用相同的规则。
以下列表配置了一个 ReactiveLoadBalancerClientFilter
:
示例 65. application.yml
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
注意 | 注意 | 注意 |
---|---|---|
默认情况下,当 ReactorLoadBalancer 找不到服务实例时,返回 503 。您可以通过设置 spring.cloud.gateway.loadbalancer.use404=true 来配置网关返回 404 。 | ||
从 ReactiveLoadBalancerClientFilter 返回的 ServiceInstance 的 isSecure 值覆盖了向 Gateway 发出的请求中指定的方案。例如,如果请求通过 HTTPS 进入 Gateway,但 ServiceInstance 指示它不安全,则下游请求将通过 HTTP 发出。相反的情况也可以应用。 然而,如果网关配置中的路由指定了 GATEWAY_SCHEME_PREFIX_ATTR ,则前缀被剥离,路由 URL 中的结果方案覆盖了 ServiceInstance 配置。 |
7.8. RouteToRequestUrl 过滤器
如果在 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR
交换属性中存在 Route
对象,则 RouteToRequestUrlFilter
运行。它创建一个新的 URI,基于请求 URI 但更新了 Route
对象的 URI 属性。新的 URI 被放置在 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中。
如果 URI 有一个方案前缀,例如 lb:ws://serviceid
,则 lb
方案从 URI 中剥离并放置在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
中,以便在过滤器链中后续使用。
7.9. Websocket 路由过滤器
如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的 URL 有一个 ws
或 wss
方案,则 Websocket 路由过滤器运行。它使用 Spring Websocket 基础设施将 Websocket 请求转发到下游。
您可以通过在 URI 前缀 lb
来对 Websockets 进行负载均衡,例如 lb:ws://serviceid
。
注意 | 注意 | 注意 |
---|---|---|
如果您使用 SockJS 作为正常 HTTP 的回退,您还应该配置一个正常的 HTTP 路由以及 Websocket 路由。 |
以下列表配置了一个 Websocket 路由过滤器:
示例 66. application.yml
spring:
cloud:
gateway:
routes:
# SockJS 路由
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# 正常 Websocket 路由
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**
7.10. 标记交换为已路由
在网关路由了 ServerWebExchange
之后,它通过向交换属性添加 gatewayAlreadyRouted
来将该交换标记为“已路由”。一旦请求被标记为已路由,其他路由过滤器将不再路由请求,基本上跳过该过滤器。您可以使用方便的方法来标记交换为已路由或检查交换是否已经被路由。
ServerWebExchangeUtils.isAlreadyRouted
接受一个ServerWebExchange
对象并检查它是否已经被“路由”。ServerWebExchangeUtils.setAlreadyRouted
接受一个ServerWebExchange
对象并将其标记为“已路由”。
HttpHeadersFilters
在将请求发送到下游之前应用于请求,例如在 NettyRoutingFilter
中。
Forwarded
头过滤器创建一个 Forwarded
头以发送到下游服务。它将当前请求的 Host
头、方案和端口添加到任何现有的 Forwarded
头中。
RemoveHopByHop
头过滤器从转发请求中删除头。默认删除的头列表来自 IETF。
默认删除的头有:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailer
- Transfer-Encoding
- Upgrade
要更改此设置,将 spring.cloud.gateway.filter.remove-hop-by-hop.headers
属性设置为要删除的头名称列表。
XForwarded
头过滤器创建各种 X-Forwarded-*
头以发送到下游服务。它使用当前请求的 Host
头、方案、端口和路径来创建各种头。
可以通过以下布尔属性(默认为 true)控制创建各个头:
spring.cloud.gateway.x-forwarded.for-enabled
spring.cloud.gateway.x-forwarded.host-enabled
spring.cloud.gateway.x-forwarded.port-enabled
spring.cloud.gateway.x-forwarded.proto-enabled
spring.cloud.gateway.x-forwarded.prefix-enabled
可以通过以下布尔属性(默认为 true)控制附加多个头:
spring.cloud.gateway.x-forwarded.for-append
spring.cloud.gateway.x-forwarded.host-append
spring.cloud.gateway.x-forwarded.port-append
spring.cloud.gateway.x-forwarded.proto-append
spring.cloud.gateway.x-forwarded.prefix-append
9. TLS 和 SSL
网关可以通过遵循常规的 Spring 服务器配置来监听 HTTPS 请求。以下示例展示了如何操作:
示例 67. application.yml
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
您可以将网关路由到 HTTP 和 HTTPS 后端。如果您正在路由到 HTTPS 后端,您可以配置网关信任所有下游证书,如下所示:
示例 68. application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
使用不安全的 Trust Manager 不适合生产环境。对于生产部署,您可以使用以下配置,配置网关信任一组已知的证书:
示例 69. application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
如果 Spring Cloud Gateway 没有提供信任的证书,将使用默认的信任存储(您可以通过设置 javax.net.ssl.trustStore
系统属性来覆盖它)。
9.1. TLS 握手
网关维护了一个客户端池,它用于路由到后端。当通过 HTTPS 通信时,客户端启动 TLS 握手。与此握手相关联的有多个超时。您可以配置这些超时(默认值如下):
示例 70. application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0
10. 配置
Spring Cloud Gateway 的配置由一系列 RouteDefinitionLocator
实例驱动。以下列表显示了 RouteDefinitionLocator
接口的定义:
示例 71. RouteDefinitionLocator.java
public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}
默认情况下,PropertiesRouteDefinitionLocator
使用 Spring Boot 的 @ConfigurationProperties
机制加载属性。
前面配置示例都使用了使用位置参数而不是命名参数的快捷符号。以下两个示例是等效的:
示例 72. application.yml
spring:
cloud:
gateway:
routes:
- id: setstatus_route
uri: https://example.org
filters:
- name: SetStatus
args:
status: 401
- id: setstatusshortcut_route
uri: https://example.org
filters:
- SetStatus=401
对于网关的一些使用情况,属性是足够的,但是一些生产用例从从外部源(如数据库)加载配置中受益。未来的里程碑版本将有基于 Spring Data Repositories 的 RouteDefinitionLocator
实现,如 Redis、MongoDB 和 Cassandra。
10.1. RouteDefinition 指标
要启用 RouteDefinition
指标,请将 spring-boot-starter-actuator 添加为项目依赖。然后,默认情况下,只要 spring.cloud.gateway.metrics.enabled
属性设置为 true
,指标将可用。将添加一个名为 spring.cloud.gateway.routes.count
的计量器指标,其值为 RouteDefinitions
的数量。此指标将从 /actuator/metrics/spring.cloud.gateway.routes.count
可用。
您可以使用元数据为每个路由配置额外的参数,如下所示:
示例 73. application.yml
spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1
您可以按以下方式从交换中获取所有元数据属性:
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// 获取所有元数据属性
route.getMetadata();
// 获取单个元数据属性
route.getMetadata(someKey);
12. HTTP 超时配置
可以为所有路由配置 HTTP 超时(响应和连接),并为每个特定路由覆盖。
12.1. 全局超时
要配置全局 HTTP 超时:
connect-timeout
必须以毫秒为单位指定。
response-timeout
必须指定为 java.time.Duration。
全局 HTTP 超时示例
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
12.2. 每路由超时
要配置每路由超时:
connect-timeout
必须以毫秒为单位指定。
response-timeout
必须以毫秒为单位指定。
通过配置配置每路由 HTTP 超时
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200
使用 Java DSL 配置每路由超时
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
return routeBuilder.routes()
.route("test1", r -> {
return r.host("*.somehost.org").and().path("/somepath")
.filters(f -> f.addRequestHeader("header1", "header-value-1"))
.uri("http://someuri")
.metadata(RESPONSE_TIMEOUT_ATTR, 200)
.metadata(CONNECT_TIMEOUT_ATTR, 200);
})
.build();
}
如果每路由 response-timeout
有一个负值,它将禁用全局 response-timeout
值。
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: -1
13. 流畅的 Java 路由 API
为了在 Java 中允许简单的配置,RouteLocatorBuilder
bean 包括一个流畅的 API。以下列表展示了它的工作原理:
示例 74. GatewaySampleApplication.java
// 从 GatewayFilters 和 RoutePredicates 进行静态导入
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80"))
.route(r -> r.path("/image/webp")
.filters(f ->
f.addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
.metadata("key", "value"))
.route(r -> r.order(-1)
.host("**.throttle.org").and().path("/get")
.filters(f -> f.filter(throttle.apply(1,
1,
10,
TimeUnit.SECONDS)))
.uri("http://httpbin.org:80")
.metadata("key", "value"))
.build();
}
这种风格还允许更多的自定义断言断言。由 RouteDefinitionLocator
beans 定义的断言使用逻辑 and
组合。通过使用流畅的 Java API,您可以在 Predicate
类上使用 and()
、or()
和 negate()
操作符。
14. DiscoveryClient
路由定义定位器
您可以配置网关,根据在 DiscoveryClient
兼容的服务注册表中注册的服务来创建路由。
要启用此功能,请设置 spring.cloud.gateway.discovery.locator.enabled=true
并确保 DiscoveryClient
实现(例如 Netflix Eureka、Consul 或 Zookeeper)在类路径上并启用。
14.1. 为 DiscoveryClient
路由配置断言和过滤器
默认情况下,网关为使用 DiscoveryClient
创建的路由定义了一个单一的断言和一个过滤器。
默认断言是使用模式 /serviceId/**
定义的路径断言,其中 serviceId
是来自 DiscoveryClient
的服务 ID。
默认过滤器是带有正则表达式 /serviceId/?(?<remaining>.*)
和替换 /${remaining}
的重写路径过滤器。这在将请求发送到下游之前从路径中剥离了服务 ID。
如果您想自定义 DiscoveryClient
路由使用的断言或过滤器,设置 spring.cloud.gateway.discovery.locator.predicates[x]
和 spring.cloud.gateway.discovery.locator.filters[y]
。这样做时,您需要确保包括前面显示的默认断言和过滤器,如果您想保留该功能。以下示例展示了这是什么样子:
示例 75. application.properties
spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"
15. Reactor Netty 访问日志
要启用 Reactor Netty 访问日志,设置 -Dreactor.netty.http.server.accessLogEnabled=true
。
注意 | 注意 | 注意 |
---|---|---|
它必须是一个 Java 系统属性,而不是 Spring Boot 属性。 |
您可以配置日志系统以拥有一个单独的访问日志文件。以下示例创建了一个 Logback 配置:
示例 76. logback.xml
<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
<file>access_log.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="accessLog" />
</appender>
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
<appender-ref ref="async"/>
</logger>
16. CORS 配置
您可以配置网关控制全局或每路由的 CORS 行为。两者都提供相同的可能性。
16.1. 全局 CORS 配置
示例 77. application.yml
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
前面的示例允许来自 docs.spring.io
的请求,对于所有 GET 请求的路径,允许 CORS 请求。
要为不受某些网关路由断言处理的请求提供相同的 CORS 配置,将 spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping
属性设置为 true
。当您尝试支持 CORS 预请求,并且您的路由断言由于 HTTP 方法是 options
而没有评估为 true
时,这很有用。
16.2. 路由 CORS 配置
“route” 配置允许将 CORS 直接作为元数据应用到路由上,使用 cors
作为键。像全局配置一样,属性属于 Spring Framework CorsConfiguration
。
注意 | 注意 | 注意 |
---|---|---|
如果路由中没有 Path 断言,'/***' 将被应用。 |
示例 78. application.yml
spring:
cloud:
gateway:
routes:
- id: cors_route
uri: https://example.org
predicates:
- Path=/service/**
metadata:
cors:
allowedOrigins: '*'
allowedMethods:
- GET
- POST
allowedHeaders: '*'
maxAge: 30
17. 执行器 API
/gateway
执行器端点允许您监视和与 Spring Cloud Gateway 应用程序交互。要使端点可远程访问,必须在应用程序属性中启用并公开端点,通过 HTTP 或 JMX。
以下列表展示了如何这样做:
示例 79. application.properties
management.endpoint.gateway.enabled=true # 默认值
management.endpoints.web.exposure.include=gateway
这个端点提供了对子执行器端点上可用内容的概述,以及每个引用的可用方法。结果响应类似于以下内容:
[
{
"href":"/actuator/gateway/",
"methods":["GET"]
},
{
"href":"/actuator/gateway/routedefinitions",
"methods":["GET"]
},
{
"href":"/actuator/gateway/globalfilters",
"methods":["GET"]
},
{
"href":"/actuator/gateway/routefilters",
"methods":["GET"]
},
{
"href":"/actuator/gateway/routes",
"methods":["POST","GET"]
},
{
"href":"/actuator/gateway/routepredicates",
"methods":["GET"]
},
{
"href":"/actuator/gateway/refresh",
"methods":["POST"]
},
{
"href":"/actuator/gateway/routes/route-id-1/combinedfilters",
"methods":["GET"]
},
{
"href":"/actuator/gateway/routes/route-id-1",
"methods":["POST","DELETE","GET"]
}
]
17.1. 详细执行器格式
Spring Cloud Gateway 中添加了一种新的、更详细的格式。它为每个路由添加了更多细节,让您可以查看与每个路由相关联的断言和过滤器以及任何可用的配置。
以下示例配置了 /actuator/gateway/routes
:
[
{
"predicate": "(Hosts: [**.addrequestheader.org] &&& Paths: [/headers], match trailing slash: true)",
"route_id": "add_request_header_test",
"filters": [
"[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]",
"[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]",
"[[PrefixPath prefix = '/httpbin'], order = 2]"
],
"uri": "lb://testservice",
"order": 0
}
]
此功能默认启用。要禁用它,请设置以下属性:
示例 80. application.properties
spring.cloud.gateway.actuator.verbose.enabled=false
这将在未来的版本中默认为 true
。
17.2. 检索路由过滤器
本节详细介绍了如何检索路由过滤器,包括:
-
全局过滤器
-
[gateway-route-filters]
17.2.1. 全局过滤器
要检索应用于所有路由的全局过滤器,请向 /actuator/gateway/globalfilters
发送 GET
请求。结果响应类似于以下内容:
{
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5": 10100,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
}
响应包含了当前正在使用的全局过滤器的详细信息。对于每个全局过滤器,都有一个过滤器对象的字符串表示(例如,org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5
)和过滤器链中的相应顺序。
17.2.2. 路由过滤器
要检索应用于路由的 GatewayFilter
工厂,请向 /actuator/gateway/routefilters
发送 GET
请求。结果响应类似于以下内容:
{
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}
响应包含了应用于任何特定路由的 GatewayFilter
工厂的详细信息。对于每个工厂,都有一个相应对象的字符串表示(例如,[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]
)。请注意,null
值是由于端点控制器的实现不完整,因为它尝试设置对象在过滤器链中的顺序,这并不适用于 GatewayFilter
工厂对象。
17.3. 刷新路由缓存
要清除路由缓存,请向 /actuator/gateway/refresh
发送 POST
请求。请求返回 200,没有响应正文。
要清除与特定元数据值匹配的路由,请添加查询参数 metadata
,指定要清除的路由应匹配的 key:value
对。如果在异步刷新期间出现错误,刷新将不会修改现有路由。
发送 POST
请求到 /actuator/gateway/refresh?metadata=group:group-1
将仅刷新其 group
元数据为 group-1
的路由:first_route
和 third_route
。
[
{
"route_id": "first_route",
"route_object": {
"predicate": "..."
},
"metadata": {
"group": "group-1"
}
},
{
"route_id": "second_route",
"route_object": {
"predicate": "..."
},
"metadata": {
"group": "group-2"
}
},
{
"route_id": "third_route",
"route_object": {
"predicate": "..."
},
"metadata": {
"group": "group-1"
}
}
]
17.4. 检索网关中定义的路由
要检索网关中定义的路由,请向 /actuator/gateway/routes
发送 GET
请求。结果响应类似于以下内容:
[
{
"route_id": "first_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d",
"filters": [
"OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"
]
},
"order": 0
},
{
"route_id": "second_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
"filters": []
},
"order": 0
}
]
响应包含了网关中定义的所有路由的详细信息。下面的表格描述了响应中每个元素(每个是一个路由)的结构:
路径 | 类型 | 描述 |
---|---|---|
route_id | String | 路由 ID。 |
route_object.predicate | Object | 路由断言。 |
route_object.filters | Array | 应用于路由的 GatewayFilter 工厂。 |
order | Number | 路由顺序。 |
17.5. 检索特定路由的信息
要检索有关单个路由的信息,请向 /actuator/gateway/routes/{id}
发送 GET
请求(例如,/actuator/gateway/routes/first_route
)。结果响应类似于以下内容:
{
"id": "first_route",
"predicates": [
{
"name": "Path",
"args": {
"_genkey_0":"/first"
}
}
],
"filters": [],
"uri": "https://www.uri-destination.org",
"order": 0
}
下面的表格描述了响应的结构:
路径 | 类型 | 描述 |
---|---|---|
id | String | 路由 ID。 |
predicates | Array | 路由断言的集合。每个项目定义了给定断言的名称和参数。 |
filters | Array | 应用于路由的过滤器集合。 |
uri | String | 路由的目标 URI。 |
order | Number | 路由顺序。 |
17.6. 创建和删除特定路由定义
要创建路由定义,请向 /gateway/routes/{id_route_to_create}
发送带有指定路由字段的 JSON 正文的 POST
请求(见检索有关特定路由的信息)。
要删除路由定义,请向 /gateway/routes/{id_route_to_delete}
发送 DELETE
请求。
17.7. 创建多个路由定义
要在单个请求中创建多个路由定义,请向 /gateway/routes
发送带有指定路由字段的 JSON 正文的 POST
请求,包括路由 ID(见检索有关特定路由的信息)。如果在创建路由期间任何路由引发错误,将丢弃路由定义。
17.8. 所有端点的总结
下面的表格总结了 Spring Cloud Gateway 执行器端点(请注意,每个端点的基本路径为 /actuator/gateway
):
ID | HTTP 方法 | 描述 |
---|---|---|
globalfilters | GET | 显示应用于路由的全局过滤器列表。 |
routefilters | GET | 显示应用于特定路由的 GatewayFilter 工厂列表。 |
refresh | POST | 清除路由缓存。 |
routes | GET | 显示网关中定义的路由列表。 |
routes/{id} | GET | 显示有关特定路由的信息。 |
routes/{id} | POST | 向网关添加新路由。 |
routes/{id} | DELETE | 从网关中移除现有路由。 |
17.9. 在多个 Gateway 实例之间共享路由
Spring Cloud Gateway 提供了两种 RouteDefinitionRepository
实现。第一种是 InMemoryRouteDefinitionRepository
,它只存在于一个 Gateway 实例的内存中。这种类型的存储库不适合在多个 Gateway 实例之间填充路由。
为了在 Spring Cloud Gateway 实例的集群中共享路由,可以使用 RedisRouteDefinitionRepository
。要启用这种类型的存储库,必须将以下属性设置为 true:spring.cloud.gateway.redis-route-definition-repository.enabled
。与 RedisRateLimiter 过滤器工厂一样,它需要使用 spring-boot-starter-data-redis-reactive Spring Boot 启动器。
18. 故障排除
本节涵盖了使用 Spring Cloud Gateway 时可能出现的常见问题。
18.1. 日志级别
以下记录器在 DEBUG
和 TRACE
级别可能包含有价值的故障排除信息:
org.springframework.cloud.gateway
org.springframework.http.server.reactive
org.springframework.web.reactive
org.springframework.boot.autoconfigure.web
reactor.netty
redisratelimiter
18.2. 监听
Reactor Netty HttpClient
和 HttpServer
可以启用监听。当与将 reactor.netty
日志级别设置为 DEBUG
或 TRACE
结合使用时,它启用了记录信息,例如发送和接收的头和正文。
要启用监听,请设置 spring.cloud.gateway.httpserver.wiretap=true
或 spring.cloud.gateway.httpclient.wiretap=true
,分别用于 HttpServer
和 HttpClient
。
19. 开发者指南
这些是编写网关的一些自定义组件的基本指南。
19.1. 编写自定义路由断言工厂
为了编写路由断言,您需要实现 RoutePredicateFactory
作为 bean。有一个名为 AbstractRoutePredicateFactory
的抽象类,您可以扩展它。
MyRoutePredicateFactory.java
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// 从 Config 对象中获取配置
return exchange -> {
// 获取请求
ServerHttpRequest request = exchange.getRequest();
// 从请求中获取信息以查看它是否匹配配置。
return matches(config, request);
};
}
public static class Config {
// 在此处放置您的过滤器的配置属性
}
}
19.2. 编写自定义网关过滤器工厂
要编写 GatewayFilter
,您必须实现 GatewayFilterFactory
作为 bean。您可以扩展一个名为 AbstractGatewayFilterFactory
的抽象类。以下示例展示了如何操作:
示例 81. PreGatewayFilterFactory.java
@Component
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
public PreGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// 从 Config 对象中获取配置
return (exchange, chain) -> {
// 如果您想构建一个“预”过滤器,您需要在调用 chain.filter 之前操作请求
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
// 使用构建器操作请求
return chain.filter(exchange.mutate().request(builder.build()).build());
};
}
public static class Config {
// 在此处放置您的过滤器的配置属性
}
}
PostGatewayFilterFactory.java
@Component
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// 从 Config 对象中获取配置
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
// 以某种方式操作响应
}));
};
}
public static class Config {
// 在此处放置您的过滤器的配置属性
}
}
19.2.1. 命名自定义过滤器和在配置中的引用
自定义过滤器的类名应该以 GatewayFilterFactory
结尾。
例如,要在配置文件中引用名为 Something
的过滤器,该过滤器必须位于名为 SomethingGatewayFilterFactory
的类中。
注意 | 注意 | 注意 |
---|---|---|
可以创建一个没有 GatewayFilterFactory 后缀的网关过滤器,例如 class AnotherThing 。这个过滤器可以在配置文件中被引用为 AnotherThing 。这不是一个支持的命名约定,这种语法可能在未来的版本中被移除。请更新过滤器名称以符合规范。 |
19.3. 编写自定义全局过滤器
要编写自定义全局过滤器,您必须实现 GlobalFilter
接口作为 bean。这将将过滤器应用于所有请求。
以下示例展示了如何分别设置全局预过滤器和全局后过滤器:
@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal()
.map(Principal::getName)
.defaultIfEmpty("Default User")
.map(userName -> {
// 向代理请求添加头
exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
return exchange;
})
.flatMap(chain::filter);
}
@Bean
public GlobalFilter customGlobalPostFilter() {
return (exchange, chain) -> chain.filter(exchange)
.then(Mono.just(exchange))
.map(serverWebExchange -> {
// 向响应添加头
serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked" : "It did not work");
return serverWebExchange;
})
.then();
}
20. 使用 Spring MVC 或 Webflux 构建简单的网关
注意 | 注意 | 注意 |
---|---|---|
以下描述了一种替代风格的网关。前面的文档不适用于以下内容。 |
Spring Cloud Gateway 提供了一个名为 ProxyExchange
的实用对象。您可以在常规的 Spring Web 处理器中作为一个方法参数使用它。它通过反射 HTTP 动词的方法支持基本的下游 HTTP 交换。在 MVC 中,它还通过 forward()
方法支持转发到本地处理器。
要使用 ProxyExchange
,请在类路径中包含正确的模块(spring-cloud-gateway-mvc
或 spring-cloud-gateway-webflux
)。
以下 MVC 示例将请求代理到 /test
下游到远程服务器:
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
以下示例使用 Webflux 执行相同的操作:
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
ProxyExchange
上的便利方法使处理器方法能够发现并增强传入请求的 URI 路径。例如,您可能想要提取路径的尾部元素以便将其传递给下游:
@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
网关处理器方法可以使用 Spring MVC 和 Webflux 的所有特性。因此,您可以注入请求头和查询参数,并且您可以在映射注解的声明中约束传入的请求。有关这些特性的更多详细信息,请参阅 Spring MVC 中的 @RequestMapping
文档。
您可以通过在 ProxyExchange
上使用 header()
方法向下游响应添加头。
您也可以通过向 get()
方法(和其他方法)添加一个映射器来操作响应头(和响应中的任何其他内容)。映射器是一个函数,它接受传入的 ResponseEntity
并将其转换为传出的 ResponseEntity
。
默认情况下,为“敏感”头(cookie
和 authorization
)提供了一流的支持,这些头不会传递给下游,以及“代理”(x-forwarded-*
)头。
21. AOT 和原生镜像支持
自 4.0.0
起,Spring Cloud Gateway 支持 Spring AOT 转换和原生镜像。
如果您使用负载均衡路由,您需要显式定义您的 LoadBalancerClient
服务 ID。您可以通过使用 @LoadBalancerClient
注解的 value
或 name
属性或作为 spring.cloud.loadbalancer.eager-load.clients
属性的值来实现。 |
22. 配置属性
要查看所有与 Spring Cloud Gateway 相关的配置属性列表,请参见附录。
以下是 Spring Cloud Gateway 常见应用程序属性的翻译,这些属性可以在您的 application.properties
文件、application.yml
文件中指定,或作为命令行开关使用。
这个附录提供了 Spring Cloud Gateway 的常见属性列表,以及使用它们的底层类的引用。
名称 | 默认值 | 描述 |
---|---|---|
spring.cloud.gateway.default-filters | 应用于每条路由的过滤器定义列表。 | |
spring.cloud.gateway.discovery.locator.enabled | false | 启用 DiscoveryClient 网关集成的标志。 |
spring.cloud.gateway.discovery.locator.filters | ||
spring.cloud.gateway.discovery.locator.include-expression | true | 用于评估是否将服务包含在网关集成中的 SpEL 表达式,默认为 true。 |
spring.cloud.gateway.discovery.locator.lower-case-service-id | false | 在谓词和过滤器中将 serviceId 小写化的选项,默认为 false。在使用 Eureka 时很有用,因为 Eureka 会自动将 serviceId 大写,所以 MYSERVICE 将匹配 /myservice/** |
spring.cloud.gateway.discovery.locator.predicates | ||
spring.cloud.gateway.discovery.locator.route-id-prefix | 路由 ID 的前缀,默认为 discoveryClient.getClass().getSimpleName() + “_”。将附加服务 ID 以创建 routeId。 | |
spring.cloud.gateway.discovery.locator.url-expression | 'lb://'+serviceId | 创建每条路由 URI 的 SpEL 表达式,默认为:‘lb://’+serviceId。 |
spring.cloud.gateway.enabled | true | 启用网关功能。 |
spring.cloud.gateway.fail-on-route-definition-error | true | 路由定义错误时失败的选项,默认为 true。否则,会记录警告。 |
spring.cloud.gateway.filter.add-request-header.enabled | true | 启用 add-request-header 过滤器。 |
spring.cloud.gateway.filter.add-request-parameter.enabled | true | 启用 add-request-parameter 过滤器。 |
spring.cloud.gateway.filter.add-response-header.enabled | true | 启用 add-response-header 过滤器。 |
spring.cloud.gateway.filter.circuit-breaker.enabled | true | 启用 circuit-breaker 过滤器。 |
spring.cloud.gateway.filter.dedupe-response-header.enabled | true | 启用 dedupe-response-header 过滤器。 |
spring.cloud.gateway.filter.fallback-headers.enabled | true | 启用 fallback-headers 过滤器。 |
spring.cloud.gateway.filter.hystrix.enabled | true | 启用 hystrix 过滤器。 |
spring.cloud.gateway.filter.json-to-grpc.enabled | true | 启用 JSON 到 gRPC 过滤器。 |
spring.cloud.gateway.filter.local-response-cache.enabled | false | 启用 local-response-cache 过滤器。 |
spring.cloud.gateway.filter.local-response-cache.request.no-cache-strategy | ||
spring.cloud.gateway.filter.local-response-cache.size | 为此路由逐出条目的最大缓存大小(以 KB、MB 和 GB 为单位)。 | |
spring.cloud.gateway.filter.local-response-cache.time-to-live | 5m | 缓存项过期的时间(以 s 表示秒,m 表示分钟,h 表示小时)。 |
spring.cloud.gateway.filter.map-request-header.enabled | true | 启用 map-request-header 过滤器。 |
spring.cloud.gateway.filter.modify-request-body.enabled | true | 启用 modify-request-body 过滤器。 |
spring.cloud.gateway.filter.modify-response-body.enabled | true | 启用 modify-response-body 过滤器。 |
spring.cloud.gateway.filter.prefix-path.enabled | true | 启用 prefix-path 过滤器。 |
spring.cloud.gateway.filter.preserve-host-header.enabled | true | 启用 preserve-host-header 过滤器。 |
spring.cloud.gateway.filter.redirect-to.enabled | true | 启用 redirect-to 过滤器。 |
spring.cloud.gateway.filter.remove-hop-by-hop.headers | ||
spring.cloud.gateway.filter.remove-hop-by-hop.order | 0 | |
spring.cloud.gateway.filter.remove-request-header.enabled | true | 启用 remove-request-header 过滤器。 |
spring.cloud.gateway.filter.remove-request-parameter.enabled | true | 启用 remove-request-parameter 过滤器。 |
spring.cloud.gateway.filter.remove-response-header.enabled | true | 启用 remove-response-header 过滤器。 |
spring.cloud.gateway.filter.request-header-size.enabled | true | 启用 request-header-size 过滤器。 |
spring.cloud.gateway.filter.request-header-to-request-uri.enabled | true | 启用 request-header-to-request-uri 过滤器。 |
spring.cloud.gateway.filter.request-rate-limiter.default-key-resolver | ||
spring.cloud.gateway.filter.request-rate-limiter.default-rate-limiter | ||
spring.cloud.gateway.filter.request-rate-limiter.enabled | true | 启用 request-rate-limiter 过滤器。 |
spring.cloud.gateway.filter.request-size.enabled | true | 启用 request-size 过滤器。 |
spring.cloud.gateway.filter.retry.enabled | true | 启用 retry 过滤器。 |
spring.cloud.gateway.filter.rewrite-location-response-header.enabled | true | 启用 rewrite-location-response-header 过滤器。 |
spring.cloud.gateway.filter.rewrite-location.enabled | true | 启用 rewrite-location 过滤器。 |
spring.cloud.gateway.filter.rewrite-path.enabled | true | 启用 rewrite-path 过滤器。 |
spring.cloud.gateway.filter.rewrite-request-parameter.enabled | true | 启用 rewrite-request-parameter 过滤器。 |
spring.cloud.gateway.filter.rewrite-response-header.enabled | true | 启用 rewrite-response-header 过滤器。 |
spring.cloud.gateway.filter.save-session.enabled | true | 启用 save-session 过滤器。 |
spring.cloud.gateway.filter.secure-headers.content-security-policy | default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline' | |
spring.cloud.gateway.filter.secure-headers.content-type-options | nosniff | |
spring.cloud.gateway.filter.secure-headers.disable | ||
spring.cloud.gateway.filter.secure-headers.download-options | noopen | |
spring.cloud.gateway.filter.secure-headers.enabled | true | 启用 secure-headers 过滤器。 |
spring.cloud.gateway.filter.secure-headers.frame-options | DENY | |
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies | none | |
spring.cloud.gateway.filter.secure-headers.referrer-policy | no-referrer | |
spring.cloud.gateway.filter.secure-headers.strict-transport-security | max-age=631138519 | |
spring.cloud.gateway.filter.secure-headers.xss-protection-header | 1 ; mode=block | |
spring.cloud.gateway.filter.set-path.enabled | true | 启用 set-path 过滤器。 |
spring.cloud.gateway.filter.set-request-header.enabled | true | 启用 set-request-header 过滤器。 |
spring.cloud.gateway.filter.set-request-host-header.enabled | true |
RoutePredicateHandlerMapping
的顺序。
名称 | 默认值 | 描述 |
---|---|---|
spring.cloud.gateway.httpclient.compression | false | 为 Netty HttpClient 启用压缩。 |
spring.cloud.gateway.httpclient.connect-timeout | 连接超时(毫秒),默认为 30 秒。 | |
spring.cloud.gateway.httpclient.max-header-size | 最大响应头大小。 | |
spring.cloud.gateway.httpclient.max-initial-line-length | 最大初始行长度。 | |
spring.cloud.gateway.httpclient.pool.acquire-timeout | 仅适用于类型 FIXED,获取时等待的最长时间(毫秒)。 | |
spring.cloud.gateway.httpclient.pool.eviction-interval | 0 | 在指定的时间间隔内定期执行后台驱逐检查。默认禁用(Duration.ZERO )。 |
spring.cloud.gateway.httpclient.pool.max-connections | 仅适用于类型 FIXED,开始对现有连接进行挂起获取之前的最大连接数。 | |
spring.cloud.gateway.httpclient.pool.max-idle-time | 通道将被关闭的时间(毫秒)。如果为 NULL,则没有最大空闲时间。 | |
spring.cloud.gateway.httpclient.pool.max-life-time | 通道将被关闭的持续时间。如果为 NULL,则没有最大生命周期。 | |
spring.cloud.gateway.httpclient.pool.metrics | false | 启用通道池指标的收集,并在 Micrometer 中注册。默认禁用。 |
spring.cloud.gateway.httpclient.pool.name | proxy | 通道池映射的名称,默认为 proxy。 |
spring.cloud.gateway.httpclient.pool.type | HttpClient 使用的池类型,默认为 ELASTIC。 | |
spring.cloud.gateway.httpclient.proxy.host | Netty HttpClient 代理配置的主机名。 | |
spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern | 应直接到达、绕过代理的配置主机列表的正则表达式(Java)。 | |
spring.cloud.gateway.httpclient.proxy.password | Netty HttpClient 代理配置的密码。 | |
spring.cloud.gateway.httpclient.proxy.port | Netty HttpClient 代理配置的端口。 | |
spring.cloud.gateway.httpclient.proxy.type | Netty HttpClient 代理配置的代理类型。 | |
spring.cloud.gateway.httpclient.proxy.username | Netty HttpClient 代理配置的用户名。 | |
spring.cloud.gateway.httpclient.response-timeout | 响应超时。 | |
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout | 3000ms | SSL close_notify 刷新超时。默认为 3000 毫秒。 |
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout | 0 | SSL close_notify 读取超时。默认为 0 毫秒。 |
spring.cloud.gateway.httpclient.ssl.handshake-timeout | 10000ms | SSL 握手超时。默认为 10000 毫秒。 |
spring.cloud.gateway.httpclient.ssl.key-password | 密钥密码,默认与 keyStorePassword 相同。 | |
spring.cloud.gateway.httpclient.ssl.key-store | Netty HttpClient 的密钥库路径。 | |
spring.cloud.gateway.httpclient.ssl.key-store-password | 密钥库密码。 | |
spring.cloud.gateway.httpclient.ssl.key-store-provider | Netty HttpClient 的密钥库提供者,可选字段。 | |
spring.cloud.gateway.httpclient.ssl.key-store-type | JKS | Netty HttpClient 的密钥库类型,默认为 JKS。 |
spring.cloud.gateway.httpclient.ssl.trusted-x509-certificates | 用于验证远程端点证书的受信任证书。 | |
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager | false | 安装 netty InsecureTrustManagerFactory。这是不安全的,不适合生产环境。 |
spring.cloud.gateway.httpclient.websocket.max-frame-payload-length | 最大帧负载长度。 | |
spring.cloud.gateway.httpclient.websocket.proxy-ping | true | 将 ping 帧代理到下游服务,默认为 true。 |
spring.cloud.gateway.httpclient.wiretap | false | 为 Netty HttpClient 启用 wiretap 调试。 |
spring.cloud.gateway.httpserver.wiretap | false | 为 Netty HttpServer 启用 wiretap 调试。 |
spring.cloud.gateway.loadbalancer.use404 | false | |
spring.cloud.gateway.metrics.enabled | false | 启用指标数据的收集。 |
spring.cloud.gateway.metrics.prefix | spring.cloud.gateway | 由网关发出的所有指标的前缀。 |
spring.cloud.gateway.metrics.tags | 添加到指标的标签映射。 | |
spring.cloud.gateway.observability.enabled | true | 是否应该打开 Micrometer 可观测性支持。 |
spring.cloud.gateway.predicate.after.enabled | true | 启用 after 谓词。 |
spring.cloud.gateway.predicate.before.enabled | true | 启用 before 谓词。 |
spring.cloud.gateway.predicate.between.enabled | true | 启用 between 谓词。 |
spring.cloud.gateway.predicate.cloud-foundry-route-service.enabled | true | 启用 cloud-foundry-route-service 谓词。 |
spring.cloud.gateway.predicate.cookie.enabled | true | 启用 cookie 谓词。 |
spring.cloud.gateway.predicate.header.enabled | true | 启用 header 谓词。 |
spring.cloud.gateway.predicate.host.enabled | true | 启用 host 谓词。 |
spring.cloud.gateway.predicate.method.enabled | true | 启用 method 谓词。 |
spring.cloud.gateway.predicate.path.enabled | true | 启用 path 谓词。 |
spring.cloud.gateway.predicate.query.enabled | true | 启用 query 谓词。 |
spring.cloud.gateway.predicate.read-body.enabled | true | 启用 read-body 谓词。 |
spring.cloud.gateway.predicate.remote-addr.enabled | true | 启用 remote-addr 谓词。 |
spring.cloud.gateway.predicate.weight.enabled | true | 启用 weight 谓词。 |
spring.cloud.gateway.predicate.xforwarded-remote-addr.enabled | true | 启用 xforwarded-remote-addr 谓词。 |
spring.cloud.gateway.redis-rate-limiter.burst-capacity-header | X-RateLimit-Burst-Capacity | 返回突发容量配置的头名称。 |
spring.cloud.gateway.redis-rate-limiter.config | ||
spring.cloud.gateway.redis-rate-limiter.include-headers | true | 是否包含包含速率限制器信息的头,默认为 true。 |
spring.cloud.gateway.redis-rate-limiter.remaining-header | X-RateLimit-Remaining | 返回当前秒内剩余请求数的头名称。 |
spring.cloud.gateway.redis-rate-limiter.replenish-rate-header | X-RateLimit-Replenish-Rate | 返回填充速率配置的头名称。 |
spring.cloud.gateway.redis-rate-limiter.requested-tokens-header | X-RateLimit-Requested-Tokens | 返回请求令牌配置的头名称。 |
spring.cloud.gateway.restrictive-property-accessor.enabled | true | 限制 SpEL 中的方法和属性访问。 |
spring.cloud.gateway.routes | 路由列表。 | |
spring.cloud.gateway.set-status.original-status-header-name | 包含代理请求 HTTP 代码的头名称。 | |
spring.cloud.gateway.streaming-media-types | ||
spring.cloud.gateway.x-forwarded.enabled | true | 是否启用 XForwardedHeadersFilter。 |
spring.cloud.gateway.x-forwarded.for-append | true | 是否启用将 X-Forwarded-For 作为列表追加。 |
spring.cloud.gateway.x-forwarded.for-enabled | true | 是否启用 X-Forwarded-For。 |
spring.cloud.gateway.x-forwarded.host-append | true | 是否启用将 X-Forwarded-Host 作为列表追加。 |
spring.cloud.gateway.x-forwarded.host-enabled | true | 是否启用 X-Forwarded-Host。 |
spring.cloud.gateway.x-forwarded.order | 0 | XForwardedHeadersFilter 的顺序。 |
spring.cloud.gateway.x-forwarded.port-append | true | 是否启用将 X-Forwarded-Port 作为列表追加。 |
spring.cloud.gateway.x-forwarded.port-enabled | true | 是否启用 X-Forwarded-Port。 |
spring.cloud.gateway.x-forwarded.prefix-append | true | 是否启用将 X-Forwarded-Prefix 作为列表追加。 |
spring.cloud.gateway.x-forwarded.prefix-enabled | true | 是否启用 X-Forwarded-Prefix。 |
spring.cloud.gateway.x-forwarded.proto-append | true | 是否启用将 X-Forwarded-Proto 作为列表追加。 |
spring.cloud.gateway.x-forwarded.proto-enabled | true | 是否启用 X-Forwarded-Proto。 |
A.1. 可观测性 - 指标
以下是此项目声明的所有指标的列表。
A.1.1. 网关 HttpClient 观测
通过网关发送请求时创建的观测。
指标名称 http.client.requests
(由惯例类 org.springframework.cloud.gateway.filter.headers.observation.Default.active
(由惯例类 org.springframework.cloud.gateway.filter.headers.observation.DefaultGatewayObservationConvention
定义)。类型 long task timer
。
关键值在开始观测后添加的可能不会出现在 *.active 指标中。 | |
Micrometer 内部使用 nanoseconds 作为基础单位。但是,每个后端确定实际的基础单位。(即 Prometheus 使用秒) |
完整限定名的封闭类 org.springframework.cloud.gateway.filter.headers.observation.GatewayDocumentedObservation
。
名称 | 描述 |
http.method (必需) | HTTP 方法。 |
http.status_code (必需) | HTTP 状态。 |
spring.cloud.gateway.route.id (必需) | 路由 ID。 |
spring.cloud.gateway.route.uri (必需) | 从路由中获取的 HTTP URI。 |
表 1. 低基数键
名称 | 描述 |
http.uri (必需) | 完整的 HTTP URI。 |
表 2. 高基数键
A.2. 可观测性 - Spans
以下是此项目声明的所有 spans 的列表。
A.2.1. 网关 HttpClient 观测 Span
通过网关发送请求时创建的观测。
Span 名称 http.client.requests
(由惯例类 org.springframework.cloud.gateway.filter.headers.observation.DefaultGatewayObservationConvention
定义)。
完整限定名的封闭类 org.springframework.cloud.gateway.filter.headers.observation.GatewayDocumentedObservation
。
名称 | 描述 |
http.method (必需) | HTTP 方法。 |
http.status_code (必需) | HTTP 状态。 |
http.uri (必需) | 完整的 HTTP URI。 |
spring.cloud.gateway.route.id (必需) | 路由 ID。 |
spring.cloud.gateway.route.uri (必需) | 从路由中获取的 HTTP URI。 |
表 3. 标签键
A.3. 可观测性 - 惯例
以下是此项目声明的所有 GlobalObservabilityConventions
和 ObservabilityConventions
的列表。
适用的观测上下文类名称 | 观测惯例类名称 |
GatewayContext | org.springframework.cloud.gateway.filter.headers.observation.DefaultGatewayObservationConvention |
表 4. 观测惯例实现