软件开发定制定制Spring Cloud Gateway 参考指南

👏大家好,欢迎来到👏阿提说说👏博客
🌞“软件开发定制定制纸上得来终觉浅,软件开发定制定制绝知此事要躬行。”(南宋)陆游

🌲软件开发定制定制目前相关的教程虽然有很多,软件开发定制定制但总觉得被各位大佬压缩,软件开发定制定制看到的只是一部分知识,并不全面,软件开发定制定制因此作者根据Spring Cloud Gateway 软件开发定制定制官方参考指南写下了这软件开发定制定制篇中文版文字教程,软件开发定制定制并且录制了一些视频教程,软件开发定制定制希望更有助于您理解。

🍀Spring Cloud Gateway 版本为 3.1.3

软件开发定制定制该项目提供了一个基于Spring生态的API网关。Spring Cloud Gateway。Spring Cloud Gateway软件开发定制定制旨在提供一个种简单有软件开发定制定制效的方式去路由API,并给API软件开发定制定制提供相应关注点:如:security、monitoring/metrics和resiliency。

1. 如何引入Spring Cloud Gateway

软件开发定制定制要在项目中引入Spring Cloud Gateway,软件开发定制定制您可以这样做:

  1. 引入Spring Cloud 软件开发定制定制统一版本依赖管理,软件开发定制定制通过引入该配置,无需指定Spring Cloud软件开发定制定制相关组件版本
<dependencyManagement>	<dependencies>		<dependency>			<groupId>org.springframework.cloud</groupId>			<artifactId>spring-cloud-dependencies</artifactId>			<version>${spring-cloud.version}</version>			<type>pom</type>			<scope>import</scope>		</dependency>	</dependencies></dependencyManagement>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  1. 引入Spring Cloud Gateway配置
<dependency>	<groupId>org.springframework.cloud</groupId>	<artifactId>spring-cloud-starter-gateway</artifactId></dependency>
  • 1
  • 2
  • 3
  • 4

🚩 软件开发定制定制如果引入了Spring Cloud Gateway,软件开发定制定制又不想开启,可以设置spring.cloud.gateway.enabled=false

❗️ Spring Cloud Gateway建立在, 和 之上,当您使用Spring Cloud Gateway时,软件开发定制定制以前的同步库(Spring Data 、Spring Security等)并不适用。软件开发定制定制如果您不熟悉这些项目,软件开发定制定制建议您在使用Spring Cloud Gateway之前,软件开发定制定制先阅读他们的文档,软件开发定制定制熟悉一些概念。

❗️ Spring Cloud Gateway 使用Spring Boot 和Spring Webflux 提供的Netty环境运行,软件开发定制定制因此在传统的Servlet软件开发定制定制容器中不会生效。

2. 相关术语

  • Route: 路由,软件开发定制定制网关基础模块。它由ID、目标URI、软件开发定制定制断言集合和过滤器集合组成。软件开发定制定制如果断言为真,软件开发定制定制则匹配到该路由。
  • Predicate:这是一个 软件开发定制定制的函数断言。软件开发定制定制输入类型是Spring Framework 的 。
  • Filter: 软件开发定制定制使用指定工厂构建的GatewayFilter的实例。在这里,软件开发定制定制您能够修改request请求和response软件开发定制定制返回在发送到下游服务软件开发定制定制之前或者之后。

3. 如何工作

下图是SPring Cloud Gateway软件开发定制定制的工作示意图:

客户端向Spring Cloud Gateway请求。软件开发定制定制如果网关处理程序(Gateway Handler Mapping)软件开发定制定制确定请求与路由匹配,软件开发定制定制那么将其发送到网关的Web处理器(Gateway Web Handler)。软件开发定制定制该处理程序通过过滤器软件开发定制定制链来处理请求。过滤器链被虚线分割的原因是,过滤器可以在请求发送前后运行逻辑,先执行所有的“pre”过滤器逻辑,后执行“post”过滤器逻辑。

✅ 在未定义端口的URI中,HTTP默认为80,HTTPS默认为443。

4. 配置路由断言工厂和网关过滤工厂

有两种方法配置谓词和过滤器:简写和完全展开方式。下面的例子大都用的简写。

4.1 简写

简写配置由过滤器名称,后跟等号,后跟逗号分割的参数值。

application.yml

spring:  cloud:    gateway:      routes:      - id: after_route        uri: https://example.org        predicates:        - Cookie=mycookie,mycookievalue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.2 完全展开

完全展开方式具有标准的name/value 对。一般带有name 和 args 两个key。args用来配置断言或过滤器的键值对映射。

application.yml

spring:  cloud:    gateway:      routes:      - id: after_route        uri: https://example.org        predicates:        - name: Cookie          args:            name: mycookie            regexp: mycookievalue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5. 路由断言工厂

Spring Cloud Gateway 路由匹配作为Spring WebFlux HandlerMapping 基础设施的一部分。Spring Cloud Gateway内置了很多路由断言工厂。用于匹配HTTP请求的不同属性。

5.1 After Route Predicate Factory

接收一个java ZonedDateTime的时间参数,表示这个时间之后的请求才能正确匹配路由。

Example 1.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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这个路由匹配 Jan 20, 2017 17:42 Mountain Time (Denver)之后的请求。

5.2 Before Route Predicate Factory

接收一个Java ZonedDateTime类的时间参数,表示这个时间之前的请求才能正确匹配路由。

Example 2. 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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.3 Between Route Predicate Factory

接收两个Java ZonedDateTime类的时间参数,表示在第一个时间之后,第二个时间之前的请求才能正确匹配路由。

Example 3. 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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.4 Cookie Route Predicate Factory

接收两个参数,分别为name 和 regexp(Java正则表达式),表示cookie中携带的name值满足正则表达式regexp,则被路由。

Example 4. application.yml

spring:  cloud:    gateway:      routes:      - id: cookie_route        uri: https://example.org        predicates:        - Cookie=chocolate, ch.p
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.5 Route Predicate Factory

接收两个参数,header 和 regexp(Java正则表达式),表示header中携带的name值满足正则表达式regexp,则被路由

Example 5. application.yml

spring:  cloud:    gateway:      routes:      - id: header_route        uri: https://example.org        predicates:        - Header=X-Request-Id, \d+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.6 Host Route Predicate Factory

接收一个主机名称的集合参数,用逗号分割,表示该断言与主机头匹配则被路由。

Example 6. application.yml

spring:  cloud:    gateway:      routes:      - id: host_route        uri: https://example.org        predicates:        - Host=**.somehost.org,**.anotherhost.org
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

支持URI模板变量(如{sub}.myhost.org)。
当Host 头的值为www.somehost.org 或 beta.somehost.org 或 www.anotherhost.org都能匹配该路由。

Predicate 会提取URI模板变量作为map集合,并放置在ServerWebExchange.getAttributes()中,key定义为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE,这些值能在GatewayFilter 工厂中使用。

5.7 Mehtod Route Predicate Factory

接收一个或多个http请求参数,如果请求方法匹配,则被路由。

Example 7. application.yml

spring:  cloud:    gateway:      routes:      - id: method_route        uri: https://example.org        predicates:        - Method=GET,POST
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.8 Path Route Predicate Factory

接收两个参数,分别是Spring PathMatcher patterns 列表 和 一个matchTrailingSlash的可选标志(默认为true)。

Example 8. application.yml

spring:  cloud:    gateway:      routes:      - id: path_route        uri: https://example.org        predicates:        - Path=/red/{segment},/blue/{segment}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果请求地址是 /red/1 或 /red/1/ 或 /red/blue 或 /blue/green,那么路由将会被匹配。

如果matchTrailingSlash 设置为false,那么/red/1/不会被匹配。

Predicate 会提取URI模板变量作为map集合,并放置在ServerWebExchange.getAttributes()中,key定义为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE,这些值能在GatewayFilter 工厂中使用。

可以使用一个实用方法(调用get)来简化对这些变量的访问。下面的例子展示了如何使用get方法:

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);String segment = uriVariables.get("segment");
  • 1
  • 2
  • 3

5.9 Query Route Predicate Factory

接收两个参数,分别是一个必须的param和一个可选的regexp。

Example 9. application.yml

spring:  cloud:    gateway:      routes:      - id: query_route        uri: https://example.org        predicates:        - Query=green
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

application.yml

spring:  cloud:    gateway:      routes:      - id: query_route        uri: https://example.org        predicates:        - Query=red, gree.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果请求中包含一个red查询参数,且该参数的值匹配gree.正则表达式,则上述路由匹配。所以green和greet是匹配的。

5.10 RemoteAddr Route Predicate Factory

接收一个sources列表(最小1个),CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是一个IP地址,16是一个子网掩码)。

Example 10. application.yml

spring:  cloud:    gateway:      routes:      - id: remoteaddr_route        uri: https://example.org        predicates:        - RemoteAddr=192.168.1.1/24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果请求的远程地址是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 值产生以下远程地址:

maxTrustedIndexresult
[Integer.MIN_VALUE,0](invalid, IllegalArgumentException during initialization)
10.0.0.3
20.0.0.2
30.0.0.1
[4, Integer.MAX_VALUE]0.0.0.1

以下示例显示了如何使用 Java 实现相同的配置:

Example 11. GatewayConfig.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"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5.11 Weight Route Predicate Factory

接收两个参数:分别是group 和 weight(int类型)。权重是按组计算的。

Example 12. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

将有80%的流量被路由到weighthigh.org,20%的流量被路由到weightlow.org

5.12 XForwarded Remote Addr Route Predicate Factory

接收一个sources列表(最小大小为 1),这些源是 CIDR 表示法(IPv4 或 IPv6)字符串,例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子网掩码)

此路由断言允许基于 X-Forwarded-For HTTP 标头过滤请求。

这可以与反向代理一起使用,例如负载平衡器或 Web 应用程序防火墙,其中仅当请求来自这些反向代理使用的受信任的 IP 地址列表时才允许请求。

以下示例配置 XForwardedRemoteAddr 路由谓词:

Example 13. application.yml

spring:  cloud:    gateway:      routes:      - id: xforwarded_remoteaddr_route        uri: https://example.org        predicates:        - XForwardedRemoteAddr=192.168.1.1/24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果 X-Forwarded-For 标头包含例如 192.168.1.10,则此路由匹配。

6. 网关过滤器工厂(GatewayFilter)

路由过滤器允许修改传入的HTTP请求和传出的HTTP响应。Spring Cloud Gateway包括了许多内置的GatewayFilter Factories。

关于过滤器的更多示例,查看。

6.1 AddRequestHeader GatewayFilter Factory

接收一个namevalue参数,并将信息添加到下游的请求头中。

Example 14. application.yml

spring:  cloud:    gateway:      routes:      - id: add_request_header_route        uri: https://example.org        filters:        - AddRequestHeader=X-Request-red, blue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

AddRequestHeader支持使用URI变量来匹配path 或 host。

Example 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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.2 AddRequestParameter GatewayFilter Factory

接收一个name 和 value 参数,并添加信息到下游的请求中。

Example 16. application.yml

spring:  cloud:    gateway:      routes:      - id: add_request_parameter_route        uri: https://example.org        filters:        - AddRequestParameter=red, blue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

支持使用URI变量来匹配path 或 host。

Example 17. 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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.3 AddResponseHeader GatewayFilter Factory

接收一个name 和 value 参数,并将信息添加到下游匹配请求的响应头中。

Example 18. application.yml

spring:  cloud:    gateway:      routes:      - id: add_response_header_route        uri: https://example.org        filters:        - AddResponseHeader=X-Response-Red, Blue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

支持使用URI变量来匹配path 或 host。

Example 19. 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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.4 DedupeResponseHeader GatewayFilter Factory

接收一个name参数和一个可选的strategy参数,name 参数根据空格分割。

Example 20. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

当网关CROS和下游响应头都有Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin时,将删除重复的响应头。

DedupeResponseHeader过滤器也接收可选的strategy参数,可接收的值是RETAIN_FIRST (default), RETAIN_LAST 和 RETAIN_UNIQUE

6.5 CircuitBreaker GatewayFilter Factory(演示)

使用 Spring Cloud CircuitBreaker的API将网关路由包装到断路器中。Spring Cloud CircuitBreaker 支持多种库用于Spring Cloud Gateway。比如Resilience4J。

要启用Spring Cloud CircuitBreaker过滤器,你需要引入spring-cloud-starter-circuitbreaker-reactor-resilience4j,如下是配置示例:

Example 21. application.yml

spring:  cloud:    gateway:      routes:      - id: circuitbreaker_route        uri: https://example.org        filters:        - CircuitBreaker=myCircuitBreaker
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

要配置 circuit breaker,可以详细查看

Spring Cloud CircuitBreaker 过滤器也支持接收可选的fallbackUri参数。当前,仅forward:支持,如果请求失败,请求将会跳转到匹配URI的controller中。

Example 22. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

🚩 RewritePath 表示将/consumingServiceEndpoint路径在请求前重写为/backingServiceEndpoint

下面是Java的实现方式:

Example 23. Application.java

@Beanpublic 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();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

当前请求被熔断时,将被回调到/inCaseofFailureUseThis

✅ 动图演示

gateway: 测试网关
backing-service: 测试后端服务

  • 熔断跳转到inCaseOfFailureUseThis

  • 重写跳转到backingServiceEndpoint

这里fallbackUri主要使用在网关应用程序内部定义controller或者handler。您也可以重路由到外部应用程序。如下示例:

Example 24. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

该示例中,网关没有fallback 端点或处理程序。但是注册了一个localhost:9994的应用程序。

在请求被转发到fallback的时候,Spring Cloud CircuitBreaker Gateway filter 也提供Throwable异常。它被添加到ServerWebExchange ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR中,以便可以在网关应用程序中使用。

对于外部controller/handler场景,可以添加带有异常详情信息的头。您可以在中找到更多详情。

6.5.1 根据状态码熔断

通过配置的statusCodes,当返回配置的状态码时,请求熔断。状态码可以配置整型状态码值或者HttpStatus的枚举字符串。

Example 25. 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"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Java 代码表示

Example 26. Application.java

@Beanpublic 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();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

6.6 FallbackHeaders GatewayFilter Factory

FallbackHeaders 工厂允许您在转发到外部应用程序的fallbackUri中添加Spring Cloud CircuitBreaker 详细的异常信息,如下所示:

Example 27. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在该例中,在运行circuit breaker 发生异常后,请求将被转发到http://localhost:9994/fallback中。异常类型、消息等通过FallbackHeaders过滤器添加到请求头中。

通过设置下面列出的参数值,可以在配置中覆盖headers的名称。

  • executionExceptionTypeHeaderName (“Execution-Exception-Type”)
  • executionExceptionMessageHeaderName (“Execution-Exception-Message”)
  • rootCauseExceptionTypeHeaderName (“Root-Cause-Exception-Type”)
  • rootCauseExceptionMessageHeaderName (“Root-Cause-Exception-Message”)

更多详情查看

6.7 MapRequestHeader GatewayFilter Factory(演示)

接收两个参数,分别是fromHeader 和 toHeader。它会创建一个新的header(toHeader),并从fromHeader中提取值。如果输入的header不存在,该过滤器不会执行。如果新的header已经存在,那么它将被追加新值。如下所示:

Example 28. application.yml

spring:  cloud:    gateway:      routes:      - id: map_request_header_route        uri: https://example.org        filters:        - MapRequestHeader=Blue, X-Request-Red
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该示例会将X-Request-Red:<values>头添加到下游请求中,值为传入的HTTP请求Blue值。

✅视频演示

6.8 PrefixPath GatewayFilter Factory

接收一个参数prefix

Example 29. application.yml

spring:  cloud:    gateway:      routes:      - id: prefixpath_route        uri: https://example.org        filters:        - PrefixPath=/mypath
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该示例将在所有匹配请求路径前加上前缀/mypath,因此请求/hello时,将发送到/mypath/hello中。

6.9 PreserveHostHeader GatewayFilter Factory(演示)

该过滤工厂没有接收参数。设置了该Filter后,GatewayFilter将不使用由HTTP客户端确定的host header ,而是发送原始host header。

Example 30. application.yml

spring:  cloud:    gateway:      routes:      - id: preserve_host_route        uri: https://example.org        filters:        - PreserveHostHeader
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

✅视频演示

6.10 RequestRateLimiter GatewayFilter Factory

该过滤器使用RateLimiter来实现是否允许继续执行该请求。如果不允许继续执行,返回HTTP 429 - Too Many Requests(默认情况下)。

该过滤器可以配置一个可选的keyResolver 参数和rate limiter参数。

keyResolverKeyResolver的一个实现类,在配置中,按名称使用SpEL引用bean。#{@myKeyResolver}是引用名为’myKeyResolver’的bean的SpEL表达式。

Example 31. KeyResolver.java

public interface KeyResolver {    Mono<String> resolve(ServerWebExchange exchange);}
  • 1
  • 2
  • 3

KeyResolver接口允许使用可插拔策略来派生限制请求的key。在未来的里程碑版本中,将有一些KeyResolver实现。

KeyResolver的默认实现是PrincipalNameKeyResolver,它从ServerWebExchange检索Principal并调用Principal.getName()

默认情况下,如果KeyResolver 没有获取到key,请求将被拒绝。您可以通过如下设置来调整:
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true or false)
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code

❗️ RequestRateLimiter 不能使用“shortcut”来配置,如下配置无效:

# INVALID SHORTCUT CONFIGURATIONspring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
  • 1
  • 2

6.10.1 Redis RateLimiter(演示)

Redis实现基于。它需要引入spring-boot-starter-data-redis-reactive依赖。

使用的算法是。

redis-rate-limiter.replenishRate配置是在不丢弃任何请求的情况下,你允许用户每秒执行多少请求。这是令牌桶的填充速率。

redis-rate-limiter.burstCapacity配置是允许用户在一秒内执行的最大请求数。这是令牌桶可以保存的令牌数。将此值设置为0将阻止所有请求。

redis-rate-limiter.requestedTokens配置一个请求所需要的令牌数。每个请求从令牌桶提取的令牌数,默认为1。

通过在replenishRateburstCapacity中设置相同的值来实现稳定的速率。可通过设置burstCapacity高于replenishRate来允许临时突发流量。在这种情况下,限流器需要在两次突发之间留出一段时间(根据replenishRate),因为连续两次突发将导致请求丢失 (HTTP 429 - Too Many Requests)。如下列表配置了一个redis-rate-limiter:

比如:replenishRate=1requestedTokens=60burstCapacity=60将限制为 1 request/min

Example 33. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

配置一个KeyResolver

**Example 34. Config.java

@BeanKeyResolver userKeyResolver() {    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));}
  • 1
  • 2
  • 3
  • 4

这定义了每个用户10个请求的限制。允许20个突发,但下一秒只有10个请求可用。KeyResolver是一个简单的获取user请求参数的工具(注意:不建议用于生产)。

限流器也可以定义为RateLimiter接口的实现 bean。在配置中,按名称使用SpEL引用bean。#{@myRateLimiter}是引用名为myRateLimiter的bean的SpEL表达式。

Example 35. application.yml

spring:  cloud:    gateway:      routes:      - id: requestratelimiter_route        uri: https://example.org        filters:        - name: RequestRateLimiter          args:            rate-limiter: "#{@myRateLimiter}"            key-resolver: "#{@userKeyResolver}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

✅视频演示

6.11 RedirectTo GatewayFilter Factory

接收两个参数:statusurl
status是300类重定向HTTP码,如301。该url应该是一个有效的URL,值是Location header的值。
对于相对路径,应该使用uri: no://op作为路由定义。

Example 36. application.yml

spring:  cloud:    gateway:      routes:      - id: prefixpath_route        uri: https://example.org        filters:        - RedirectTo=302, https://acme.org
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该例将发送一个302重定向状态码到Location:https://acme.org

6.12 RemoveRequestHeader GatewayFilter Factory

接收一个name参数,该值是将要被删除header的name。

Example 37. application.yml

spring:  cloud:    gateway:      routes:      - id: removerequestheader_route        uri: https://example.org        filters:        - RemoveRequestHeader=X-Request-Foo
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该例表示将从header中删除X-Request-Foo

6.13 RemoveResponseHeader GatewayFilter Factory

接收一个参数name,name将在响应返回之前被删除。

Example 38. application.yml

spring:  cloud:    gateway:      routes:      - id: removeresponseheader_route        uri: https://example.org        filters:        - RemoveResponseHeader=X-Response-Foo
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该例表示响应在返回网关之前将从header中删除X-Response-Foo

可以使用spring.cloud.gateway.default-filters配置默认过滤,该默认过滤对所有路由有效。

6.14 RemoveRequestParameter GatewayFilter Factory

接收一个name参数,它是要被删除请求参数的name值。

Example 39. application.yml

spring:  cloud:    gateway:      routes:      - id: removerequestparameter_route        uri: https://example.org        filters:        - RemoveRequestParameter=red
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该例表示在将请求发送到下游之前,删除red参数。

6.15 RequestHeaderSize GatewayFilter Factory

接收两个参数,maxSizeerrorHeaderName
maxSize表示请求头的最大数据带下(包括key和value)。errorHeaderName用于设置响应头的名称,包含错误信息,默认名称为errorMessage

Example 40. application.yml

spring:  cloud:    gateway:      routes:      - id: requestheadersize_route        uri: https://example.org        filters:        - RequestHeaderSize=1000B
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该示例表示如果请求超过了1000Bytes,将发送一个431的状态码。

6.16 RewritePath GatewayFilter Factory

接收一个regexpreplacement参数。使用了Java正则表达式来重写请求地址。

Example 41. application.yml

spring:  cloud:    gateway:      routes:      - id: rewritepath_route        uri: https://example.org        predicates:        - Path=/red/**        filters:        - RewritePath=/red/?(?<segment>.*), /$\{segment}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对于/red/blue请求路径,将在发送到下游之前替换为/blue。因为YAML规范,要把$替换为$\

6.17 RewriteLocationResponseHeader GatewayFilter Factory

该过滤器修改Location响应头的值,经常用于去掉一些敏感信息。接收参数分别是:
stripVersionMode, locationHeaderName, hostValue, protocolsRegex

Example 42. application.yml

spring:  cloud:    gateway:      routes:      - id: rewritelocationresponseheader_route        uri: http://example.org        filters:        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

示例表示,一个POST请求 api.example.com/some/object/name,Location响应头的值是object-service.prod.example.net/v2/some/object/id将被重写为api.example.com/some/object/id

stripVersionMode 参数有以下值:NEVER_STRIP, AS_IN_REQUEST (默认), 和ALWAYS_STRIP

  • NEVER_STRIP:原始的请求中不包含版本,也不会去掉版本

  • AS_IN_REQUEST:原始请求中不包含版本,响应头就去掉版本

  • ALWAYS_STRIP:始终会去掉版本

hostValue参数:如果提供该值,将用于替换host:port响应Location头的值,如果为空,则使用请求中名为Host的header值。

protocolsRegex 参数是一个有效的正则字符串。如果不匹配,则过滤器不执行。默认值为http | https | ftp | ftps。

6.18 RewriteResponseHeader GatewayFilter Factory

接收nameregexpreplacement三个参数。使用Java正则表达式重写响应header头。

Example 43. application.yml

spring:  cloud:    gateway:      routes:      - id: rewriteresponseheader_route        uri: https://example.org        filters:        - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在下游响应返回到网关后,该示例将把/42?user=ford&password=omg!what&flag=true头的值,设置为/42?user=ford&password=***&flag=true。您必须使用$\代替$

6.19 SaveSession GatewayFilter Factory

SaveSession GatewayFilter Factory将调用转发到下游之前强制执行WebSession::save 操作。这在使用 之类时特别有用,需要确保会话状态在进行转发调用之前已保存。

Example 44. application.yml

spring:  cloud:    gateway:      routes:      - id: save_session        uri: https://example.org        predicates:        - Path=/foo/**        filters:        - SaveSession
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果你希望要将与Spring Session集成,并要确保安全信息都传到下游,这样做将是很重要的。

6.20 SecureHeaders GatewayFilter Factory

根据的建议,SecureHeaders GatewayFilter Factory在response响应中添加了许多头。

添加了以下的头(默认值):

  • 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

  • x-frame-options

  • x-content-type-options

  • referrer-policy

  • content-security-policy

  • x-download-options

  • x-permitted-cross-domain-policies

使用spring.cloud.gateway.filter.secure-headers.disable禁用默认值,全小写逗号分割

6.21 SetPath GatewayFilter Factory

SetPath GatewayFilter Factory 采用一个template 路径参数。它提供了一种简单的方法,通过允许路径的模板化segments来操作请求路径。使用Spring Framework中的URI模板,允许多个匹配segments。

Example 45. application.yml

spring:  cloud:    gateway:      routes:      - id: setpath_route        uri: https://example.org        predicates:        - Path=/red/{segment}        filters:        - SetPath=/{segment}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如上所示:请求/red/blue,将在请求下游时将路径设置为/blue

6.22 SetRequestHeader GatewayFilter Factory

采用namevalue参数。

Example 46. application.yml

spring:  cloud:    gateway:      routes:      - id: setrequestheader_route        uri: https://example.org        filters:        - SetRequestHeader=X-Request-Red, Blue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该GatewayFilter将会使用给定的name替换所有的header,而不是添加。因此会将请求头从X-Request-Red:1234设置为X-Request-Red:Blue

SetRequestHeader 允许使用path或者host的URI变量。

Example 47. application.yml

spring:  cloud:    gateway:      routes:      - id: setrequestheader_route        uri: https://example.org        predicates:        - Host: {segment}.myhost.org        filters:        - SetRequestHeader=foo, bar-{segment}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.23 SetResponseHeader GatewayFilter Factory

两个参数namevalue

Example 48. application.yml

spring:  cloud:    gateway:      routes:      - id: setresponseheader_route        uri: https://example.org        filters:        - SetResponseHeader=X-Response-Red, Blue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该GatewayFilter将会使用给定的name替换所有的header,而不是添加。下游响应的头X-Response-Red:1234将会替换成X-Response-Red:Blue

SetResponseHeader 也使用path或者host的URI变量。

Example 49. application.yml

spring:  cloud:    gateway:      routes:      - id: setresponseheader_route        uri: https://example.org        predicates:        - Host: {segment}.myhost.org        filters:        - SetResponseHeader=foo, bar-{segment}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.24 SetStatus GatewayFilter Factory(演示)

接收一个参数status,必须是一个可用的Spring HttpStatus值,可用是整数或者枚举字符串。

Example 50. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

该示例,将HTTP status响应头设置为401。

使用SetStatus 可以在响应中返回代理请求中的原始Http 状态码。如下配置,将header添加到响应中。

Example 51. application.yml

spring:  cloud:    gateway:      set-status:        original-status-header-name: original-http-status
  • 1
  • 2
  • 3
  • 4
  • 5

✅演示

如下示例配置了original-status-header-name: original-http-statusSetStatus=401,效果如下:

6.25 StripPrefix GatewayFilter Factory

接收一个parts参数。 parts参数指示在将请求发送到下游之前,要从请求中去除的路径中的节数。

Example 52. application.yml

spring:  cloud:    gateway:      routes:      - id: nameRoot        uri: https://nameservice        predicates:        - Path=/name/**        filters:        - StripPrefix=2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

该示例表示当网关发送/name/blue/red请求时,实际向下游请求的地址是nameservice/red

6.26 Retry GatewayFilter Factory(演示)

Retry GatewayFilter Factory使用了reactor-addons 的retry组件进行重试,支持以下参数:

  • retries:应尝试的重试次数
  • statuses:应尝试的HTTP状态码
  • methods:应尝试的HTTP方法
  • series:应尝试的series状态码,org.springframework.http.HttpStatus.Series
  • exceptions:应尝试的异常列表
  • backoff:配置指数退避重试。根据firstBackoff * (factor ^ n)进行指数重试,maxBackoff 限制最大退避重试,如果basedOnPreviousValue 为true,则退避指数计算使用prevBackoff * factor

Retry 过滤器默认值配置如下:

  • retries: 3次
  • series: 5XX series
  • methods:GET 方法
  • exceptions:IOException 和 TimeoutException
  • backoff: disabled

Example 53. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

❗️ 当重试过滤器与任何带body的HTTP请求使用时,body会被缓存。body被缓存在请求定义的的ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR中,对象类型是:org.springframework.core.io.buffer.DataBuffer

使用单个statusmethod,可以使用简便的方式添加:
Example 54. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

✅演示

6.27 RequestSize GatewayFilter Factory

当请求大小大于允许的限制时,RequestSize GatewayFilter Factory可以限制请求不到达下游服务。过滤器以RequestSize作为参数,这是定义请求的允许大小限制(以字节为单位)。

Example 55. application.yml

spring:  cloud:    gateway:      routes:      - id: request_size_route        uri: http://localhost:8080/upload        predicates:        - Path=/upload        filters:        - name: RequestSize          args:            maxSize: 5000000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当请求因大小而被拒绝时, RequestSize GatewayFilter Factory 将响应状态设置为413 Payload Too Large,并带有额外的header errorMessage

errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
  • 1

❗️ 如果未在路由定义中作为filter参数提供,则默认请求大小将设置为5 MB

6.28 SetRequestHostHeader GatewayFilter Factory

接收一个host参数,用于覆盖主机头。

Example 56. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

该示例表示使用example.org代替host头的值。

6.29 ModifyRequestBodyGatewayFilterFactory

此过滤器可用于在请求主体被网关发送到下游之前对其进行修改。

❗️ 只能使用Java DSL配置此过滤器。如果没有body,RewriteFilter 会传递null。

@Beanpublic 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) -> return 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;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

6.30 Modify Response Body GatewayFilter Factory

此过滤器可用于在将响应正文发送回客户端之前对其进行修改。

❗️ 只能使用Java DSL配置此过滤器。如果没有body,RewriteFilter 会传递null。

@Beanpublic 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();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.31 Token Relay GatewayFilter Factory

令牌中继是OAuth2使用者充当客户端并将传入令牌转发给传出资源请求的地方。使用者可以是纯客户端(如SSO应用程序)或资源服务器。

Spring Cloud Gateway 可以将OAuth2访问令牌转发到其代理的服务下游。要将此功能添加到网关,您需要添加TokenRelayGatewayFilterFactory

App.java

@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder) {    return builder.routes()            .route("resource", r -> r.path("/resource")                    .filters(f -> f.tokenRelay())                    .uri("http://localhost:9000"))            .build();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

或者

application.yaml

spring:  cloud:    gateway:      routes:      - id: resource        uri: http://localhost:9000        predicates:        - Path=/resource        filters:        - TokenRelay=
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

它将(除了让登录和获取令牌之外)将身份验证令牌传递给下游的服务(在本例中是/resource)。

开启该功能要添加依赖到Spring Cloud Gateway

  • org.springframework.boot:spring-boot-starter-oauth2-client

工作原理:TokenRelayGatewayFilterFactory会从认证的用户中提取access token,并放入发送给下游的请求中。示例见:

❗️ ReactiveOAuth2AuthorizedClientService的默认实现是TokenRelayGatewayFilterFactory,使用内存存储,如果需要自定义,需要自己实现ReactiveOAuth2AuthorizedClientService 。

6.32 CacheRequestBody GatewayFilter Factory

由于请求body流只能读取一次,因此我们需要缓存请求的body。可以使用CacheRequestBody 缓存body,并从exchange 中获取该body。

@Beanpublic RouteLocator routes(RouteLocatorBuilder builder) {    return builder.routes()        .route("cache_request_body_route", r -> r.path("/downstream/**")            .filters(f -> f.prefixPath("/httpbin")                .cacheRequestBody(String.class).uri(uri))        .build();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Example 57. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

CacheRequestBody 将提取请求body并转换成body 指定的类。(本例中是java.lang.String)。缓存中定义的key为ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR

❗️ 仅支持http/https 请求

6.33 Default Filters

可以使用spring.cloud.gateway.default-filters作为所有路由的过滤器。该配置接收一个filter列表,如下:

Example 58. application.yml

spring:  cloud:    gateway:      default-filters:      - AddResponseHeader=X-Response-Default-Red, Default-Blue      - PrefixPath=/httpbin
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7. Global Filters

GlobalFilter接口与GatewayFilter具有相同的签名。是有条件地应用于所有路由的特殊过滤器。

❗️ 此接口和用法可能在将来的里程碑版本中发生更改

7.1 全局Filter和GatewayFilter组合排序

当请求匹配到路由时,web 过滤处理器会将所有的 GlobalFilter 实例和指定的GatewayFilter实例添加到过滤器链。filter的排序由org.springframework.core.Ordered接口决定,可以通过getOrder()方法或者@Order注释来设置。

由于Spring Cloud Gateway将用于执行过滤器逻辑区分为“前置”和“后置”阶段,具有最高优先级的过滤器将是“前置”阶段的第一个,而“后置”阶段的最后一个。

如下配置了一个过滤器链:

Example 59. ExampleConfiguration.java

@Beanpublic 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;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

7.2 Forward Routing Filter

ForwardRoutingFilter在exchange属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。如果URL有一个forward scheme (如 forward:///localendpoint),它将使用Spring DispatcherHandler 来处理请求。请求URL的路径部分将被转发URL中的路径覆盖。未修改的原始URL将附加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性中的列表中。

7.3 ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter在exchange属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。如果URL有一个lb scheme (如 lb://myservice),它将使用Spring Cloud ReactorLoadBalancer 将名称(在前一个示例中为myservice)解析为实际主机和端口,并替换URI。未修改的原始URL将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性中的列表中。过滤器还将查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性,查看它是否等于lb,然后应用相同的规则。

Example 60. application.yml

spring:  cloud:    gateway:      routes:      - id: myRoute        uri: lb://service        predicates:        - Path=/service/**
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

❗️默认情况下,如果一个服务实例在ReactorLoadBalancer中没有发现,则返回503。可以通过设置spring.cloud.gateway.loadbalancer.use404=true来让网关返回404.

❗️从ReactiveLoadBalancerClientFilter 返回的ServiceInstance的isSecure 值将覆盖在对网关发出的请求中指定的scheme。例如,如果请求通过HTTPS进入网关,但ServiceInstance表示它不安全,则下游请求将通过HTTP协议。相反的情况也适用。但是,如果在网关配置中为路由指定了GATEWAY_SCHEME_PREFIX_ATTR,则前缀将被删除,并且路由URL生成的scheme将覆盖ServiceInstance配置。

💡 Gateway支持所有LoadBalancer 能力。详情查看

7.4 Netty Routing Filter

如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR属性中的URL具有http 或https 模式,则会运行Netty Routing Filter。它使用Netty HttpClient 发出下游代理请求。响应放在 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange属性中,以便在以后的过滤器中使用。(有一个处于实验阶段的WebClientHttpRoutingFilter,不需要使用Netty)。

7.5 Netty Write Response Filter

如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange属性中存在 Netty HttpClientResponse,则运行 NettyWriteResponseFilter 。它在其他所有过滤器完成后运行,并将代理响应写回到网关客户端的响应中。(一个处于实验阶段的,不需要Netty的过滤器WebClientWriteResponseFilter

7.6 RouteToRequestUrl Filter

如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR exchange属性中存在Route对象,RouteToRequestUrlFilter将运行。它基于请求URI创建一个新的URI,使用Route对象的uri属性进行更新。新的URI被放置在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange属性中。如果该URI有一个前缀scheme,例如lb:ws://serviceid,则会从该URI中剥离该 lb scheme,并将其放置在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR中,以便稍后在过滤器链中使用。

7.7 Websocket Routing Filter

如果ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange属性中有 wswss scheme,则Websocket Routing Filter将被运行。它使用Spring Web Socket基础模块将Websocket转发到下游。

URI前缀为lb的Websockets可以被负载均衡,如 lb:ws://serviceid

❗️ 如果使用 作为普通HTTP的fallback,则应配置普通HTTP路由以及WebSocket路由。

Example 61. application.yml

spring:  cloud:    gateway:      routes:      # SockJS route      - id: websocket_sockjs_route        uri: http://localhost:3001        predicates:        - Path=/websocket/info/**      # Normal Websocket route      - id: websocket_route        uri: ws://localhost:3001        predicates:        - Path=/websocket/**
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

7.8 Gateway Metrics Filter

要启用网关指标,请将spring-boot-starter-actuator添加为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled未设置为false,网关指标过滤器就会运行。此过滤器添加名为spring.cloud.gateway.requests的计时器指标,并带有以下标记:

  • routeId: route ID.

  • routeUri: API 将被转发的URI

  • outcome: 结果分类,依据

  • status: 返回client的请求的Http Status

  • httpStatusCode: 返回client的请求的httpStatusCode

  • httpMethod: 用于请求的HTTP方法

另外通过spring.cloud.gateway.metrics.tags.path.enabled(默认为false)来激活额外的指标:

  • path:请求的路径

这些指标可以从/actuator/metrics/spring.cloud.gateway.requests获取,并且能够很容易的与Prometheus 集成创建。

❗️ 要将pometheus启用,需要添加micrometer-registry-prometheus为项目依赖。

7.9 Marking An Exchange As Routed

网关路由ServerWebExchange之后,它将通过向Exchange属性添加gatewayAlreadyRouted,将该exchange标记为“routed”。一旦一个请求被标记为routed,其他路由过滤器将不会再次路由该请求,将跳过该过滤器。有一些方便的方法可以用来将exchange标记为routed,或者检查exchange是否已经routed。

  • ServerWebExchangeUtils.isAlreadyRouted 有一个ServerWebExchange 对象用来检查是否已routed。
  • ServerWebExchangeUtils.setAlreadyRouted 有一个ServerWebExchange 对象来标记是否routed。

8. HttpHeadersFilters

HttpHeadersFilters使用在请求被发送到下游之前,比如在NettyRoutingFilter中使用到了。

8.1 Forwarded Headers Filter

Forwarded Headers Filter创建一个Forwarded 头到发送给下游的请求中。它使用当前请求的Host 头,scheme 和端口添加到任何现有的Forwarded 头中。

8.2 RemoveHopByHop Headers Filter

RemoveHopByHop 用来在请求中删除头信息。删除的默认标头列表来自。

默认删除的头信息:

  • Connection

  • Keep-Alive

  • Proxy-Authenticate

  • Proxy-Authorization

  • TE

  • Trailer

  • Transfer-Encoding

  • Upgrade

要更改此设置,通过 spring.cloud.gateway.filter.remove-hop-by-hop.headers配置要删除的头信息。

8.3 XForwarded Headers Filter

XForwarded Headers Filter 创建各种X-Forwarded-*头以发送到下游服务。它使用当前请求的Host 头、scheme、port和path来创建各种头信息。

可以通过布尔属性(默认true)来配置单个的header:

  • 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 and SSL

网关可以通过常规的 Spring server configuration 来侦听HTTPS上的请求。

Example 62. application.yml

server:  ssl:    enabled: true    key-alias: scg    key-store-password: scg1234    key-store: classpath:scg-keystore.p12    key-store-type: PKCS12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

网关路由可以路由到HTTP和HTTPS后端。如果路由到HTTPS后端,则可以将网关配置为信任所有具有证书的下游服务:

Example 63. application.yml

spring:  cloud:    gateway:      httpclient:        ssl:          useInsecureTrustManager: true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

不建议在生产环境使用不安全的信任管理器。对于生产部署,可以使用一组已知证书配置网关,这些证书可以通过以下方式进行配置:

Example 64. application.yml

spring:  cloud:    gateway:      httpclient:        ssl:          trustedX509Certificates:          - cert1.pem          - cert2.pem
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如果Spring Cloud Gateway未配置受信任证书,则使用默认信任库(可以使用系统属性javax.net.ssl.trustStore覆盖)。

9.1 TLS握手

网关会维护一个用于路由到后端的client池。当通过HTTPS通信时,客户端启动一个TLS握手,其中可能会有很多超时。这些超时可以这样配置(显示默认值):

Example 65. application.yml

spring:  cloud:    gateway:      httpclient:        ssl:          handshake-timeout-millis: 10000          close-notify-flush-timeout-millis: 3000          close-notify-read-timeout-millis: 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

10. Configuration

Spring Cloud Gateway的配置由RouteDefinitionLocator的集合实例驱动。如下是RouteDefinitionLocator的接口:

Example 66. RouteDefinitionLocator.java

public interface RouteDefinitionLocator {    Flux<RouteDefinition> getRouteDefinitions();}
  • 1
  • 2
  • 3

默认情况下,PropertiesRouteDefinitionLocator使用Spring Boot的@ConfigurationProperties机制加载属性。

以下两个方式等效:

Example 67. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

对于网关的大部分用法,配置文件方式是够用的,但一些生产用例更建议从外部源(如数据库)加载配置。未来的里程碑版本将有基于Spring Data Repositories (如Redis、MongoDB和Cassandra)的RouteDefinitionLocator实现。

10.1 RouteDefinition Metrics

开启RouteDefinition,需要添加spring-boot-starter-actuator依赖。默认spring.cloud.gateway.metrics.enabled指标是设置为true。名为spring.cloud.gateway.routes.count的指标,其值为RouteDefinitions的值。指标路径/actuator/metrics/spring.cloud.gateway.routes.count

11. Route Metadata Configuration

您可以使用metadata为每个路由配置其他参数,如下所示:

Example 68. application.yml

spring:  cloud:    gateway:      routes:      - id: route_with_metadata        uri: https://example.org        metadata:          optionName: "OptionValue"          compositeObject:            name: "value"          iAmNumber: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

您可以从exchange获取所有元数据属性,如下所示:

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);// get all metadata propertiesroute.getMetadata();// get a single metadata propertyroute.getMetadata(someKey);
  • 1
  • 2
  • 3
  • 4
  • 5

12. Http超时配置

12.1 全局超时

connect-timeout 必填,毫秒
response-timeout 必填,类型为 java.time.Duration

global http timeouts example

spring:  cloud:    gateway:      httpclient:        connect-timeout: 1000        response-timeout: 5s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

12.2 Per-route timeouts

connect-timeout 必填,毫秒
response-timeout必填,毫秒

      - id: per_route_timeouts        uri: https://example.org        predicates:          - name: Path            args:              pattern: /delay/{timeout}        metadata:          response-timeout: 200          connect-timeout: 200
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用Java DSL配置 pre-route超时

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();      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

per-route 的response-timeout为赋值的时候,全局的response-timeout将被禁用。

      - id: per_route_timeouts        uri: https://example.org        predicates:          - name: Path            args:              pattern: /delay/{timeout}        metadata:          response-timeout: -1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

12.3 流式Java Routes API

RouteLocatorBuilder 具备流式API功能。

Example 69. GatewaySampleApplication.java

// static imports from GatewayFilters and RoutePredicates@Beanpublic 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();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

这种风格运行更多的自定义断言,RouteDefinitionLocator 断言通过and组合。另外使用流式API,您可以使用and(), or(), 和negate()操作Predicate类。

12.4 DiscoveryClient Route Definition Locator

基于在DiscoveryClient兼容服务注册表中注册的服务创建路由。

使用spring.cloud.gateway.discovery.locator.enabled=true开启它,并确保DiscoveryClient 实现组件(比如Netflix Eureka, Consul, or Zookeeper)在类路径中。

12.4.1 Configuring Predicates and Filters For DiscoveryClient Routes

Example 70. application.properties

spring.cloud.gateway.discovery.locator.predicates[0].name: Pathspring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"spring.cloud.gateway.discovery.locator.predicates[1].name: Hostspring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreakerspring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceIdspring.cloud.gateway.discovery.locator.filters[1].name: RewritePathspring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

13. Reactor Netty 访问日志

开启该访问日志,设置-Dreactor.netty.http.server.accessLogEnabled=true

❗️ 它是一个Java 系统配置,而不是Spring Boot的配置。

您可以将日志记录系统配置为单独的访问日志文件。以下示例创建了一个Logback配置:

Example 71. 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

14.CORS配置

我们可以通过配置网关来控制CORS行为,全局CORS配置是 模式的URL MAP。

Example 72. application.yml

spring:  cloud:    gateway:      globalcors:        cors-configurations:          '[/**]':            allowedOrigins: "https://docs.spring.io"            allowedMethods:            - GET
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

例子中将允许从docs.spring.io发出的所有GET请求进行CORS请求。

15. Actuator API

/gateway的actuator端点允许监视Spring Cloud Gateway并与之交互。要进行远程访问,必须在应用程序属性中暴露 端口。

Example 73. application.properties

management.endpoint.gateway.enabled=true # default valuemanagement.endpoints.web.exposure.include=gateway
  • 1
  • 2

15.1 Verbose Actuator Format

它为每个路由添加了更多细节,允许您查看与每个路由相关联的谓词和过滤器以及可用的任何配置。

[  {    "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  }]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

该功能默认开启,如下设置禁用

Example 74. application.properties

spring.cloud.gateway.actuator.verbose.enabled=false
  • 1

15.2 查询 Route Filters

15.2.1 Global Filters

要查询用于所有路由的,需要发送一个GET请求到/actuator/gateway/globalfilters。结果响应类似于以下内容:

{  "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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对于每个全局过滤器,使用过滤器对象字符串表示,后面数字表示过滤器顺序。

15.2.2 Route Filters

要查询gateway Filters ,需要发送一个GET请求到/actuator/gateway/routefilters

结果响应类似于以下内容:

{  "[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,  "[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,  "[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null}
  • 1
  • 2
  • 3
  • 4
  • 5

每个工厂都有对应对象的字符串表示。null 是由于端点控制器的实现不完整,因为它试图设置过滤器链中对象的顺序,但这不适用于GatewayFilter工厂对象。

15.3 刷新 Route Cache

清除route cache ,发送POST请求到/actuator/gateway/refresh。请求返回一个200,没有响应主体。

15.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}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

响应包含网关中定义的所有路由的详细信息。下表描述了响应的每个元素(每个元素都是一个路由)的结构:

PathTypeDescription
route_idStringroute ID.
route_object.predicateObjectroute 断言.
route_object.filtersArray应用到该路由的
orderNumberroute order.

15.5 检索有关特定路由的信息

要获取单个路由的信息,发送GET请求 /actuator/gateway/routes/{id} (如: /actuator/gateway/routes/first_route),返回结果如下所示:

{  "id": "first_route",  "predicates": [{    "name": "Path",    "args": {"_genkey_0":"/first"}  }],  "filters": [],  "uri": "https://www.uri-destination.org",  "order": 0}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下面表格中描述了返回结果信息:

PathTypeDescription
idStringroute ID.
predicatesArray路由断言的集合。每个项定义给定断言的名称和参数。
filtersArray应用于路由的过滤器器集合。
uriString路由的目标URI
orderNumberroute order.

15.6 创建和删除特定路由

要创建一个路由,发送POST请求 /gateway/routes/{id_route_to_create},参数为JSON结构,具体参数数据结构参考上面章节。
要删除一个路由,发送 DELETE请求 /gateway/routes/{id_route_to_delete}

15.7 所有端点列表

下表总结了Spring Cloud Gateway启动器端点(注意,每个端点都有/actuator/gateway作为基础路径):

IDHTTP MethodDescription
globalfiltersGETDisplays the list of global filters applied to the routes.
routefiltersGETDisplays the list of GatewayFilter factories applied to a particular route.
refreshPOSTClears the routes cache.
routesGETDisplays the list of routes defined in the gateway.
routes/{id}GETDisplays information about a particular route.
routes/{id}POSTAdds a new route to the gateway.
routes/{id}DELETERemoves an existing route from the gateway.

15.8 多个网关实例之间共享路由

Spring Cloud Gateway 提供了两个RouteDefinitionRepository 实现。第一个是RouteDefinitionRepository 它只存在于一个网关实例的内存中。这种类型的存储库不适合跨多个网关实例填充路由。

为了能够共享路由,可以使用RedisRouteDefinitionRepository 。要启用此类存储库,必须将以下属性设置为true:spring.cloud.gateway.redis-route-definition-repository.enabled,它需要使用spring-boot-starter-data-redis-reactive Spring Boot starter。

16. 故障诊断

16.1 Log Levels

以下日志可能包含debug和trace级别的有价值的故障排除信息:

org.springframework.cloud.gateway

org.springframework.http.server.reactive

org.springframework.web.reactive

org.springframework.boot.autoconfigure.web

reactor.netty

redisratelimiter

16.2 Wiretap

Reactor Netty HttpClient 以及 HttpServer 可启用 Wiretap 。将reactor.netty 包设置成 debug 或 trace ,然后设置如下属性:

spring.cloud.gateway.httpserver.wiretap=true
spring.cloud.gateway.httpclient.wiretap=true

分别开启HttpServer及HttpClient的Wiretap。

17 开发者指南

编写网关自定义组件基本指南。

17.1 自定义Route Predicate Factories

实现RoutePredicateFactory 作为bean,有一个AbstractRoutePredicateFactory 抽象类用于扩展。

MyRoutePredicateFactory.java

@Componentpublic class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {    public MyRoutePredicateFactory() {        super(Config.class);    }    @Override    public Predicate<ServerWebExchange> apply(Config config) {        // grab configuration from Config object        return exchange -> {            //grab the request            ServerHttpRequest request = exchange.getRequest();            //take information from the request to see if it            //matches configuration.            return matches(config, request);        };    }    public static class Config {        //Put the configuration properties for your filter here    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

17.2 自定义GatewayFilter Factories

实现GatewayFilterFactory 作为一个bean,有一个抽象类AbstractGatewayFilterFactory用来扩展。

Example 75. PreGatewayFilterFactory.java

@Componentpublic class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {    public PreGatewayFilterFactory() {        super(Config.class);    }    @Override    public GatewayFilter apply(Config config) {        // grab configuration from Config object        return (exchange, chain) -> {            //If you want to build a "pre" filter you need to manipulate the            //request before calling chain.filter            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();            //use builder to manipulate the request            return chain.filter(exchange.mutate().request(builder.build()).build());        };    }    public static class Config {        //Put the configuration properties for your filter here    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

PostGatewayFilterFactory.java

@Componentpublic class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {    public PostGatewayFilterFactory() {        super(Config.class);    }    @Override    public GatewayFilter apply(Config config) {        // grab configuration from Config object        return (exchange, chain) -> {            return chain.filter(exchange).then(Mono.fromRunnable(() -> {                ServerHttpResponse response = exchange.getResponse();                //Manipulate the response in some way            }));        };    }    public static class Config {        //Put the configuration properties for your filter here    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

17.2.1 在配置中命名自定义过滤器和引用

自定义过滤器类名应以GatewayFilterFactory结尾。

例如,要引用配置文件中名为Something 的过滤器,该过滤器必须位于名为SomethingGatewayFilterFactory的类中。

17.3 自定义 Global Filters

实现GlobalFilter 作为bean。

以下示例分别显示了如何设置全局前置和后置过滤器:

//前置@Beanpublic GlobalFilter customGlobalFilter() {    return (exchange, chain) -> exchange.getPrincipal()        .map(Principal::getName)        .defaultIfEmpty("Default User")        .map(userName -> {          //adds header to proxied request          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();          return exchange;        })        .flatMap(chain::filter);}//后置@Beanpublic GlobalFilter customGlobalPostFilter() {    return (exchange, chain) -> chain.filter(exchange)        .then(Mono.just(exchange))        .map(serverWebExchange -> {          //adds header to response          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");          return serverWebExchange;        })        .then();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

18. 构建简单网关示例(略)

19. 配置属性

所有与Spring Cloud Gateway相关的

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发