Spring Cloud Gateway

官网原文地址

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html

3.1.3 version

因为觉得不了解网关,就去写网关。总会很多不明白的。
大致就机翻了一下,然后再去理解一遍。直接看英文版真的累。

简单高效。路由转发到相应服务的API。服务的优势,安全,监控指标,弹性,可扩展。

1、怎么配置spring cloud gateway

maven仓库。

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><version>3.1.3</version>
</dependency>

如果你不想用。可以用

spring.cloud.gateway.enabled=false

2、重要词汇表Glossary

  • 路由(Route):网关的基本构建块,一个Id,一个Url,还有一个谓语的集合,还有一个过滤器。如何聚合谓语通过为真,那么就满足了路由的条件。
  • 谓语(Predicate):java8的谓语功能。在lambda中常见。这个输入类型是 Spring Framework ServerWebExchange,这样就可以获取HTTP请求的任何东西了,包括表头和参数。
  • 过滤器(Filter):这些是由特定工厂构建的GateWayFilter的实例。从而,修改请求和相应,之前或者之后发送到下游的请求。

3、怎么工作(How it works)

下图提供了SpringCloud GateWay 如何工作的高级概述。

  1. 客户端发送请求到网关(spring cloud gateway);
  2. 如果 网关处理映射(Handler Mapping)确定(determines)了,该请求匹配上了路由,
  3. 那么这请求将会被送到网关web处理程序上。这个处理程序,通过一个特定请求过滤器链运行这个请求。
  4. 上图中,filtes之所以画虚线,是因为过滤器既可以在发送异步(代理)请求之前,也可以在之后运行逻辑。
  5. 执行所有的pre(预先)过滤器,这个代理请求完成了。在完成代理请求后,就会运行post(发布)这个过滤器逻辑。
URI如果在路由器中没有默认的端口值,那么默认端口号 http是80,httos是443.

4、配置路由谓语工厂和网关过滤器工厂

有两种配置谓语和过滤器:快捷方式和完全扩展的参数。

下面的大多数例子,都是用快捷方式。

4.1. shortcut configuration 快捷配置

快捷配置由过滤器名称识别,后面跟着等号(=),输入参数值。参数值用逗号(,)隔开。

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- Cookie=mycookie,mycookievalue

上面的样例 使用两个参数定义了cookie路由谓语工厂,也就是cookie 名称,mycookie,和匹配mycookievalue的值。

4.2.Fully Expanded Arguments 完全扩展参数

完全扩展参数发生在更多像是 带有键值对的 标准yaml配置。

(typically)通常,这将有name的key和args的key。这个args的key是为了配置谓语或者过滤器的 一个键值对的map(映射)。

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- name: Cookieargs:name: mycookieregexp: mycookievalues

上面显示的就是 Cookie断言的 快捷方式配置的完整配置。

5、Route Predicate Factories 路由谓语工厂

spring Cloud Gateway的路由匹配 作为 SpringWebFlux 处理器 映射(HandlerMapping)的基础建设的一部分。

SpringCloud Gateway包括许多内置(built-in)路由谓语工厂。所有这些谓语都匹配HTTP请求的不同属性。

你可以用逻辑和句子与多个路由断言combine(结合)起来。

5.1. The After Route Predicate Factory后置谓语工厂

After路由谓语工厂,采用一个参数。一个日期时间(这是一个Java ZonedDateTime).这个谓语匹配请求 得 发生在特定时间之后。以下示例配置了一个After路由谓语。

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]

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

5.2. The Before Route Predicate Factory 前置谓语工厂

大致意思与上面相反。

必须得发生在特定时间之前的。

spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]

这个路由 将匹配发生在 Jan 20, 2017 17:42 Mountain Time (Denver). 之前的任意请求。

5.3. The Between Route Predicate Factory 之间谓语工厂

Between路由谓语工厂,采用两个参数。datetime1和datetime2,他们是java ZonedDateTime的对象。

这个谓语 将 匹配发生在datetime1之后和datetime2之前 请求.这datetime2参数必须是在dateTime1之后。

以下示例配置了一个between路由谓语。

spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

这个路由谓语 匹配 介于 Jan 20, 2017 17:42 Mountain Time (Denver) 和Jan 21, 2017 17:42之间的任意请求。

这对于维护窗口可能很有用。

5.4. The Cookie Route Predicate Factory Cookie谓语工厂

这个Cookie路由谓语工厂采用了两个参数,cookie名称和一个正则表达式(他们是java正则表达式)。

这个谓语匹配 具有给定名称且其值与正则表达式匹配的Cookie。

下面示例,配置了Cookie路由谓语工厂。

spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p

这个路由匹配,具有叫chocolate的名称,其值与ch.p的正则表达式匹配的请求。

5.5. The Header Route Predicate Factory 表头路由谓语工厂

表头路由谓语工厂采用两个参数,这个表头和正则表达式(这是一个java正则表达式)。

这个谓语匹配一个具有给定名称,其值与正则表达式匹配的表头。下面示例配置了表头路由谓语。

spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+

如果这个请求具有一个叫 X-Request-Id,其值与\d+ 正则表达式匹配的表头,那么此路由将匹配。

5.6. The Host Route Predicate Factory 主机路由谓语工厂

这个Host路由谓语工厂采用了一个参数:主机名patterns列表。

这个样式,是一个用. 作为分隔符的 ant-style 样式。

这个谓语将匹配 匹配样式的主机表头。以下示例配置了主机路由谓语。

spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org

URI模板变量(比如{sub}.myhost.org)也是支持的。

如果请求具有一个主机表头,其值是www.somehost.org 或者 beta.somehost.org 又或者 www.anotherhost.org,那么路由将匹配。

此谓语提取URI模板变量(例如,在前面的示例中定义的sub)作为键值的映射,并将其放在 用一个定义为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE的key 的ServerWebExchange.getAttributes()。然后这些值可供gatewayFilter使用。

5.7. The Method Route Predicate Factory 方法路由谓语工厂

这个方法路由谓语工厂采用了,一个具有一个或者多个参数(匹配HTTP方法 ) , methods的参数。

以下示例配置了一个方法路由谓语。

spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST

如果请求方法是get OR post,那么这个路由将匹配。

5.8. The Path Route Predicate Factory 路径路由谓语工厂

路径路由谓语工厂采用了两个参数,一个spring的PathMatcher(路径匹配器),patterns 列表,和一个叫matchTrailingSlash (匹配尾随斜线)(默认为true)的可选择的的标志。以下示例配置路径路由谓语。

spring:cloud:gateway:routes:- id: path_routeuri: https://example.orgpredicates:- Path=/red/{segment},/blue/{segment}

如果这个请求路径是,比如:/red/1或 /red/1/ 或者 /red/blue 或者 /bule/green ,那么这个路由将匹配。

如果matchTrailingSlash( 匹配尾随斜线)设置为false,那么请求路径为/red/1/将不会被匹配。

这个谓语抽取URI模板变量(比如前面定义的例子中的 segment)作为键值映射,然后将它放到一个由ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 定义的键的ServerWebExchange.getAttributes()。这些值然后可供GatewayFilter工厂使用。

一个(叫get)的实用方法可以更轻松访问这些变量。下面示例展示了怎么使用这个get方法。

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

5.9. The Query Route Predicate Factory 查询路由谓语工厂

查询路由谓语工厂采用了两个参数:一个必须的(required)param和一个可选择regexp(这是一个java 正则表达式)。

下面示例配置了查询路由谓语。

spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=green

如果请求包含了 green的查询 参数,那么前面的路由将匹配。

spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree.

如果请求包含red的查询参数,其值匹配gree.的正则表达式,因此green和greet 都会匹配,那么前面的路由将匹配。

5.10. The RemoteAddr Route Predicate Factory 远程地址路由谓语工厂

远程路由谓语工厂才用了一个source(最小大小为1)的一个列表.其source是CIDR表示法(IPV4 OR IPV6)字符串。例如,192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。下面示例配置了一个远程地址路由谓语。

spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24

如果远程地址的请求是,例如是,192.168.1.10,那么路由就匹配了。

5.10.1. Modifying the Way Remote Addresses Are Resolved 修改远程地址的解决方式

by default(默认情况下),远程地址路由谓语工厂,使用来自传入请求的远程地址。

如果SpringCloudGateway位于代理层后面,这可能与实际客户端Ip地址不匹配。

你可以通过设置自定义RemoteAddressResolver来自定义解析远程地址的方式。

come with(附带)

SpringCloudGateway带有一个基于X-Forwarded-For表头非默认(non-default)远程地址解析器–XForwardedRemoteAddressResolver

XForwardedRemoteAddressResolver有两个静态构造方法,他们采用不同的安全方法。

  • XForwardedRemoteAddressResolver::trustAll 返回了一个RemoteAddressResolver,这个总是采用在X-Forwarded-For表头中找到第一个Ip地址。这种方法容易欺骗(spoofing),因为恶意客户单可以给X-Forwarded-For设置初始值,然后解析器会接受该值。
  • XForwardedRemoteAddressResolver::maxTrustedIndex,采用与SpringCloudGateway前面的运行的受信任的基础设施的相关索引。例如,如果SpringCloudGateway只能通过HAPrxoy,那么该值应该使用1.如果在访问SpringCloudGateway之前,需要两个被信任的基础设置,那么应该是用值2.

考虑一下标头值。

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

下面maxTrustedIndex(最大可信索引)的值产生(yield)以下远程地址。

maxTrustedIndex result
[Integer.MIN_VALUE,0] (invalid, IllegalArgumentException during initialization)
1 0.0.0.3
2 0.0.0.2
3 0.0.0.1
[4, Integer.MAX_VALUE] 0.0.0.1

下面的例子,显示用java如何实现(achieve)相同的配置。

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")
)

XForwardedRemoteAddressResolver::maxTrustedIndex得到的RemoteAddressResolver则会在X-Forwarded-For信息里面,从右到左选择信任最多maxTrustedIndex个ip,因为X-Forwarded-For是越往右是越接近gateway的代理机器ip,所以是越往右的ip,信任度是越高的。 那么如果前面只是挡了一层Nginx的话,如果只需要Nginx前面客户端的ip,则maxTrustedIndex取1,就可以比较安全地获取真实客户端ip。

5.11. 权重路由谓语工厂

权重路由谓语工厂采用两个参数:group和权重(int类型)。这个权重是按组计算的。

下面示例配置了权重路由谓语。

spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2

这个路由将会将约80%的流量转发到 weighthigh.org,然后约20%的流程转发到weighlow.org。

5.12. The XForwarded Remote Addr Route Predicate Factory XForwarded 远程地址路由谓词工厂

XForwarded Remote Addr 路由断言工厂,采用最小尺寸1的源列表。这是CIDR表示法(IPv4或IPv6)的字符串。比如192.168.0.1/16(其中192.168.0.1是Ip地址,16是子网掩码)。

这个路由谓语允许基于X-Forwarded-For的HTTP表头过滤请求。

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

以下例子配置了XForwardedRemoteAddr 路由谓语。

spring:cloud:gateway:routes:- id: xforwarded_remoteaddr_routeuri: https://example.orgpredicates:- XForwardedRemoteAddr=192.168.1.1/24

如果 X-Forwarded-For表头包含,比如是192.168.1.10,那么这个路由匹配。

6.GatewayFilter Factories 网关过滤工厂

路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路油过滤器的范围,是被限定的路由。

SpringCloudGateway包括许多内置网关过滤工厂。

6.1. The AddRequestHeader GatewayFilter Factory 添加请求标头的网关过滤器工厂

这个AddRequestHeader GatewayFilter 工厂,采用一个名称和值的参数,下面例子配置了一个AddRequest GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestHeader=X-Request-red, blue

这个清单将 X-Request-red:blue的表头到所有匹配请求的下游请求标头中。

AddRequestHeader是知道用于匹配路径或者主机的URL变量。URI变量可以在值中使用并在运行时扩展。

以下示例配置使用变量的AddRequestHeader GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- AddRequestHeader=X-Request-Red, Blue-{segment}

6.2. The AddRequestParamter GatewayFilter Factory 添加请求参数的网关过滤工厂

这个AddRequestParamter 的网关过滤工厂采用名称和值的参数。下面示例配置了添加请求参数的网关过滤。

spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blue

6.3.The AddResponseHeader GatewayFilter Factory 添加响应表头的网关过滤器工厂

这个AddResponseHeader的网关过滤工厂采用名称和值的参数。下面示例配置了AddResponseHeader网关过滤。

spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgfilters:- AddResponseHeader=X-Response-Red, Blue

这会将 X-Response-Red:Blue的表头添加到, 所有匹配的请求的下流响应表头上。

AddResponseHeader,用于匹配路径和主机,且能感知URI变量的。URI变量能在值中使用,也能在运行时扩展。下面例子 使用变量 配置了 添加响应表头的网关过滤。

spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- AddResponseHeader=foo, bar-{segment}

[6.4. The DedupeResponseHeader GatewayFilter Factory]

这个重复数据删除响应表头的网关过滤器工厂,采用了name参数和一个可选的策略(strategy)参数。name可以包含以空格分隔的 表头名称的列表 。以下示例,配置了重复数据删除 响应表头的网关过滤。

spring:cloud:gateway:routes:- id: dedupe_response_header_routeuri: https://example.orgfilters:- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

在网关CORS逻辑和下游逻辑都添加的情况下,会删除Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 响应标头的重复值。

DedupeResponseHeader 过滤器还接受可选的策略参数。接受的值为 RETAIN_FIRST(默认)、RETAIN_LAST 和 RETAIN_UNIQUE。

6.5. Spring Cloud CircuitBreaker GatewayFilter Factory springCloud断路器的网关过滤器工厂

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。

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: https://example.orgfilters:- CircuitBreaker=myCircuitBreaker

要配置断路器,请参阅您正在使用的底层断路器实现的配置。

  • Resilience4J Documentation

Spring Cloud CircuitBreaker 过滤器也可以接受一个可选的 fallbackUri 参数。目前,仅支持 forward: 计划的 URI。如果调用了fallback,则将请求转发到URI匹配的控制器。以下示例配置了这样的回退:

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

下面的清单在 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 在网关应用程序中定义内部控制器或处理程序。但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:

spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallback

在此示例中,网关应用程序中没有回退端点或处理程序。但是,在另一个应用程序中有一个,注册在 localhost:9994 下。 在请求被转发到回退的情况下,Spring Cloud CircuitBreaker Gateway 过滤器还提供导致它的 Throwable。它作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性添加到 ServerWebExchange,可在网关应用程序中处理回退时使用。 对于外部控制器/处理程序场景,可以添加带有异常详细信息的标头。您可以在 FallbackHeaders GatewayFilter Factory 部分找到有关这样做的更多信息。

6.5.1. Tripping The Circuit Breaker On Status Codes 在状态代码上使断路器跳闸

在某些情况下,您可能希望根据从其包裹的路由返回的状态代码来触发断路器。断路器配置对象采用状态代码列表,如果返回将导致断路器跳闸。在设置要使断路器跳闸的状态代码时,您可以使用带有状态代码值的整数或 HttpStatus 枚举的字符串表示形式。

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThisstatusCodes:- 500- "NOT_FOUND"
@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 6.6. The FallbackHeaders GatewayFilter Factory 回调表头网关过滤器工厂

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

spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallbackfilters:- name: FallbackHeadersargs:executionExceptionTypeHeaderName: Test-Header

在此示例中,在运行断路器时发生执行异常后,请求将转发到在 localhost:9994 上运行的应用程序中的回退端点或处理程序。 FallbackHeaders 过滤器将带有异常类型、消息和(如果可用)根本原因异常类型和消息的标头添加到该请求中。 您可以通过设置以下参数的值(显示为默认值)来覆盖配置中标头的名称:

  • executionExceptionTypeHeaderName ("Execution-Exception-Type") 执行异常类型
  • executionExceptionMessageHeaderName ("Execution-Exception-Message") 执行异常消息
  • rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type") 根本原因异常类
  • rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message") 根本原因异常消息

有关断路器和网关的更多信息,请参阅 Spring Cloud CircuitBreaker Factory section.

6.7. The MapRequestHeader GatewayFilter Factory map请求标头的网关过滤工厂

6.8. The PrefixPath GatewayFilter Factory

用了一个prefix的参数。

spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- PrefixPath=/mypath

会给所有通过匹配的请求路径,加上一个前缀/mypath.如果请求是/hello,那么被发送到/mypath/hello

谓语。

6.25.The StripPrefix GatewayFilter Factory 带前缀的网关过滤器工厂

StripPrefix GatewayFilter 工厂采用一个参数,parts。 parts 参数指示在将请求发送到下游之前要从请求中剥离的路径中的部分数。以下清单配置了 StripPrefix GatewayFilter。

大致意思,就是路径的层数。从左往右去除。

spring:cloud:gateway:routes:- id: nameRooturi: https://nameservicepredicates:- Path=/name/**filters:- StripPrefix=2

如果请求通过网关是 name/blue/red,去除两个层级,拼上url,那么对名称服务的请求,就看起来像是nameservice/red。

7. Gloabal Filters 全局过滤器

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

This interface and its usage are subject to change in future milestone releases.

7.1. Combined Global Filter and GatewayFilter Ordering 组合全局过滤器和网关过滤器排序

当请求与路由匹配时,过滤 Web 处理程序会将 GlobalFilter 的所有实例和 GatewayFilter 的所有特定于路由的实例添加到过滤器链中。这个组合过滤器链按 org.springframework.core.Ordered 接口排序,您可以通过实现 getOrder() 方法来设置。 由于 Spring Cloud Gateway 区分过滤器逻辑执行的“前”和“后”阶段(请参阅如何工作),具有最高优先级的过滤器是“前”阶段的第一个和“后”阶段的最后一个 -阶段。

所有过滤器,都会经过这个过滤器链。

优先级最高,pre的第一个。和 post的最后一个。

@Bean
public GlobalFilter customFilter() {return new CustomGlobalFilter();
}public class CustomGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("custom global filter");return chain.filter(exchange);}@Overridepublic int getOrder() {return -1;}
}

7.2 Forward Routing Filter 转发路由过滤器

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

有转发属性,forward。就用spring的DispatcherHandler 处理。

请求 URL 的路径部分被转发 URL 中的路径覆盖

原始url记录在ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR

7.3. The 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。如果是,则适用相同的规则。

url具有lb,就用 Spring Cloud ReactorLoadBalancer解析实际主机和端口,并替换同一属性中的URI。

原始的URL就放在ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 的属性中。

且适用ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR,lb可以用。

spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/**

默认情况下,当 ReactorLoadBalancer 找不到服务实例时,会返回 503。您可以通过设置 spring.cloud.gateway.loadbalancer.use404=true 来配置网关以返回 404。

从 ReactiveLoadBalancerClientFilter 返回的 ServiceInstance 的 isSecure 值会覆盖向网关发出的请求中指定的方案。例如,如果请求通过 HTTPS 进入网关,但 ServiceInstance 指示它不安全,则通过 HTTP 发出下游请求。相反的情况也可以适用。但是,如果在网关配置中为路由指定了 GATEWAY_SCHEME_PREFIX_ATTR,则会去除前缀,并且路由 URL 的结果方案会覆盖 ServiceInstance 配置。

GATEWAY_SCHEME_PREFIX_ATTR优先级高于 ReactiveLoadBalancerClientFilter 高于默认。

Gateway 支持所有 LoadBalancer 功能。您可以在Spring Cloud Commons documentation中阅读有关它们的更多信息。

7.4. The Netty Routing Filter netty路由过滤器

如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性中的 URL 具有 http 或 https 方案,则 Netty 路由过滤器运行。

它使用 Netty HttpClient 发出下游代理请求。响应放在 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中,以供以后的过滤器使用。 (还有一个实验性的 WebClientHttpRoutingFilter 执行相同的功能但不需要 Netty。)

7.5. The Netty Write Response Filter Netty Netty写响应过滤器

如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中有 Netty HttpClientResponse,则 NettyWriteResponseFilter 运行。它在所有其他过滤器完成后运行,并将代理响应写回网关客户端响应。 (还有一个实验性的 WebClientWriteResponseFilter 执行相同的功能但不需要 Netty。)

7.6. The RouteToRequestUrl Filter 路由请求地址过滤器

如果 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.7. The Websocekt Routing Filter

如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性中的 URL 具有 ws 或 wss 方案,则 websocket 路由过滤器运行。它使用 Spring WebSocket 基础设施向下游转发 websocket 请求。 您可以通过在 URI 前加上 lb 来对 websocket 进行负载平衡,例如 lb:ws://serviceid。

  • 如果你使用 SockJS 作为普通 HTTP 的后备,你应该配置一个普通的 HTTP 路由以及 websocket 路由。
spring:cloud:gateway:routes:# SockJS route- id: websocket_sockjs_routeuri: http://localhost:3001predicates:- Path=/websocket/info/**# Normal Websocket route- id: websocket_routeuri: ws://localhost:3001predicates:- Path=/websocket/**

7.8. The Gateway Metrics Filter 网关指标过滤器

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

  • routeId: 路由Id
  • routeUri: 路由地址
  • 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.9. Marking An Exchange As Routed 将交换标记为已路由

在网关路由到 ServerWebExchange 后,它通过将 gatewayAlreadyRouted 添加到交换属性来将该交换标记为“已路由”。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求,实质上是跳过过滤器。您可以使用一些便捷的方法将交换标记为已路由或检查交换是否已被路由。

跳过过滤器

  • ServerWebExchangeUtils.isAlreadyRouted 接受一个 ServerWebExchange 对象并检查它是否已被“路由”。
  • ServerWebExchangeUtils.setAlreadyRouted采用ServerWebExchange 对象,标记他为已被“路由”。

8.HttpHeadersFilter http表头过滤器

HttpHeadersFilters 在将请求发送到下游之前应用于请求,例如在 NettyRoutingFilter 中。

8.1. Forwared Headers Filter 转发表头过滤器

Forwarded Headers Filter 创建一个 Forwarded 头来发送给下游服务。它将当前请求的 Host 标头、方案和端口添加到任何现有的 Forwarded 标头。

8.2. RemoveHopByHop Headers Filter 删除

RemoveHopByHop 标头过滤器从转发的请求中删除标头。删除的默认标头列表来自 IETF。

默认删除的标题是:

  • 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 FilterXForwarded 标头过滤器

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 上的请求。以下示例显示了如何执行此操作:

server:ssl:enabled: truekey-alias: scgkey-store-password: scg1234key-store: classpath:scg-keystore.p12key-store-type: PKCS12

您可以将网关路由路由到 HTTP 和 HTTPS 后端。如果您要路由到 HTTPS 后端,则可以使用以下配置将网关配置为信任所有下游证书:

spring:cloud:gateway:httpclient:ssl:useInsecureTrustManager: true

使用不安全的信任管理器不适合生产。对于生产部署,您可以使用一组已知证书配置网关,它可以使用以下配置信任这些证书:

spring:cloud:gateway:httpclient:ssl:trustedX509Certificates:- cert1.pem- cert2.pem

如果 Spring Cloud Gateway 没有配置受信任的证书,则使用默认的信任存储(您可以通过设置 javax.net.ssl.trustStore 系统属性来覆盖它)。

9.1. TLS Handshake TLS握手

网关维护一个客户端池,用于路由到后端。通过 HTTPS 进行通信时,客户端会启动 TLS 握手。许多超时与此握手相关。您可以配置这些超时,可以按如下方式配置(显示默认值):

spring:cloud:gateway:httpclient:ssl:handshake-timeout-millis: 10000close-notify-flush-timeout-millis: 3000close-notify-read-timeout-millis: 0

10.Configuration 配置

Spring Cloud Gateway 的配置由 RouteDefinitionLocator 实例的集合驱动。以下清单显示了 RouteDefinitionLocator 接口的定义:

Example 66. RouteDefinitionLocator.java

public interface RouteDefinitionLocator {Flux<RouteDefinition> getRouteDefinitions();
}

默认情况下,PropertiesRouteDefinitionLocator 使用 Spring Boot 的 @ConfigurationProperties 机制加载属性。 早期的配置示例都使用使用位置参数而不是命名参数的快捷表示法。下面两个例子是等价的:

spring:cloud:gateway:routes:- id: setstatus_routeuri: https://example.orgfilters:- name: SetStatusargs:status: 401- id: setstatusshortcut_routeuri: https://example.orgfilters:- SetStatus=401

对于网关的某些用途,属性就足够了,但某些生产用例受益于从外部源(例如数据库)加载配置。未来的里程碑版本将具有基于 Spring Data Repositories 的 RouteDefinitionLocator 实现,例如 Redis、MongoDB 和 Cassandra。

10.1.RouteDefinition Metrics 路由定义指标

要启用 RouteDefinition 指标,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,只要属性 spring.cloud.gateway.metrics.enabled 设置为 true,这些指标就可用。将添加一个名为 spring.cloud.gateway.routes.count 的仪表度量,其值是 RouteDefinition 的数量。该指标可从 /actuator/metrics/spring.cloud.gateway.routes.count 获得。

11.Route Metadata Configuration

您可以使用元数据为每个路由配置附加参数,如下所示:

spring:cloud:gateway:routes:- id: route_with_metadatauri: https://example.orgmetadata:optionName: "OptionValue"compositeObject:name: "value"iAmNumber: 1

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

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);

12.Http timeouts configuration Http超时配置

可以为所有路由配置 Http 超时(响应和连接),并被每个特定路由覆盖。(overridden for 被覆盖)

12.1. Global timeouts 全局超时

要配置全局 http 超时:

connect-timeout: 必须以毫秒为单位指定连接超时。

response-timeout:响应超时必须指定为 java.time.Duration

global http timeouts example

spring:cloud:gateway:httpclient:connect-timeout: 1000response-timeout: 5s

12.2. Per-route timeouts 单个路由超时

要配置每条路由超时:
connect-timeout 必须以毫秒为单位指定连接超时。
response-timeout 必须以毫秒为单位指定连接超时。

用yaml配置 per-route http timeouts configuration via configuration

 - id: per_route_timeoutsuri: https://example.orgpredicates:- name: Pathargs:pattern: /delay/{timeout}metadata:response-timeout: 200connect-timeout: 200

用java配置 per-route timeouts configuration using Java DSL

import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;@Beanpublic 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();}

具有负值的每条路由响应超时将禁用全局响应超时值。

问题:不是负值,就不会禁用吗?

A per-route response-timeout with a negative value will disable the global response-timeout value.

 - id: per_route_timeoutsuri: https://example.orgpredicates:- name: Pathargs:pattern: /delay/{timeout}metadata:response-timeout: -1

12.3 Fluent Java Routes API 流畅的 Java 路由 API

为了允许在 Java 中进行简单配置,RouteLocatorBuilder bean 包含一个流畅的 API。下面的清单显示了它是如何工作的:

Example 69. GatewaySampleApplication.java

// static imports from GatewayFilters and 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 bean 定义的谓词使用逻辑与进行组合。通过使用 fluent Java API,您可以在 Predicate 类上使用 and()、or() 和 negate() 运算符。

12.4. The DiscoveryClient Route Definition DiscoveryClient 路由定义定位器

您可以将网关配置为基于向 DiscoveryClient 兼容的服务注册表注册的服务创建路由。 要启用此功能,请设置 spring.cloud.gateway.discovery.locator.enabled=true 并确保 DiscoveryClient 实现(例如 Netflix Eureka、Consul 或 Zookeeper)在类路径上并已启用。

12.4.1. Configuring Predicates and Filters For DiscoveryClient Routes 为 DiscoveryClient 路由配置谓词和过滤器

默认情况下,网关为使用 DiscoveryClient 创建的路由定义单个谓词和过滤器。 默认谓词是使用模式 /serviceId/** 定义的路径谓词,其中 serviceId 是来自 DiscoveryClient 的服务的 ID。 默认过滤器是使用正则表达式 /serviceId/?(?.*) 和替换 /${remaining} 的重写路径过滤器。这会在请求被发送到下游之前从路径中去除服务 ID。 如果要自定义 DiscoveryClient 路由使用的谓词或过滤器,请设置 spring.cloud.gateway.discovery.locator.predicates[x] 和 spring.cloud.gateway.discovery.locator.filters[y]。这样做时,如果要保留该功能,则需要确保包含前面显示的默认谓词和过滤器。以下示例显示了它的样子:

Example 70. 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}'"

13.Reactor Netty Access Logs Reactor Netty 访问日志

要启用 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>

14. CORS Configuration 跨域配置

您可以配置网关来控制 CORS 行为。 “全局”CORS 配置是 URL 模式到 Spring Framework CorsConfiguration 的映射。以下示例配置 CORS:

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "https://docs.spring.io"allowedMethods:- GET

在前面的示例中,对于所有 GET 请求路径,允许来自 docs.spring.io 的请求的 CORS 请求。 要为某些网关路由谓词未处理的请求提供相同的 CORS 配置,请将 spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping 属性设置为 true。当您尝试支持 CORS 预检请求并且您的路由谓词未评估为 true 时,这很有用,因为 HTTP 方法是选项。

15.Actuator API 执行器API

/gateway actuator 端点允许您监视 Spring Cloud Gateway 应用程序并与之交互。要远程访问,必须在应用程序属性中启用并通过 HTTP 或 JMX 公开端点。以下清单显示了如何执行此操作:

application.properties

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

15.1 Verbose Actuator Format

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}
]

默认情况下启用此功能。要禁用它,请设置以下属性:

Example 74. application.properties

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

This will default to true in a future release.

15.2. Retrieving Route Filters 检索路由过滤器

本节详细介绍如何检索路由过滤器,包括:

  • Global Filters
  • [gateway-route-filters]

15.2.1. Global Filters

要检索应用于所有路由的全局过滤器,请向 /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
}

15.2.2. Route Filters

要检索应用于路由的 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 工厂对象。

15.3.Refreshing the Route Cache 刷新路由缓存

要清除路由缓存,请向 /actuator/gateway/refresh 发出 POST 请求。该请求返回没有响应正文的 200。

15.4. Retrieving the Routes Defined in the Gateway 检索网关中定义的路由

要检索网关中定义的路由,请向 /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
}]

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

Path Type Description
route_id String The route ID.
route_object.predicate Object The route predicate.
route_object.filters Array The GatewayFilter factories applied to the route.
order Number The route order.

15.5. Retrieving Information about a Particular Route 检索有关特定路线的信息

要检索有关单个路由的信息,请向 /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
}

下表描述了响应的结构:

Path Type Description
id String The route ID.
predicates Array The collection of route predicates. Each item defines the name and the arguments of a given predicate.
filters Array The collection of filters applied to the route.
uri String The destination URI of the route.
order Number The route order.

15.6. Creating and Deleting a Particular Route 创建和删除特定路线

要创建路由,请使用指定路由字段的 JSON 正文向 /gateway/routes/{id_route_to_create} 发出 POST 请求(请参阅检索有关特定路由的信息)。 要删除路由,请向 /gateway/routes/{id_route_to_delete} 发出 DELETE 请求。

15.7. Recap: The List of All endpoints 回顾:所有端点的列表

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

ID HTTP Method Description
globalfilters GET Displays the list of global filters applied to the routes.
routefilters GET Displays the list of GatewayFilter factories applied to a particular route.
refresh POST Clears the routes cache.
routes GET Displays the list of routes defined in the gateway.
routes/{id} GET Displays information about a particular route.
routes/{id} POST Adds a new route to the gateway.
routes/{id} DELETE Removes an existing route from the gateway.

15.8. Sharing Routes between multiple Gateway instances 在多个网关实例之间共享路由

Spring Cloud Gateway 提供了两个 RouteDefinitionRepository 实现。第一个是 InMemoryRouteDefinitionRepository,它只存在于一个网关实例的内存中。这种类型的存储库不适合跨多个网关实例填充路由。 为了在 Spring Cloud Gateway 实例集群之间共享路由,可以使用 RedisRouteDefinitionRepository。要启用这种存储库,必须将以下属性设置为 true: spring.cloud.gateway.redis-route-definition-repository.enabled 与 RedisRateLimiter 过滤器工厂类似,它需要使用 spring-boot-starter-data -redis-reactive Spring Boot 启动器。

16. Troubleshooting 故障排除

本节介绍使用 Spring Cloud Gateway 时可能出现的常见问题。

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 可以启用窃听。当与将 reactor.netty 日志级别设置为 DEBUG 或 TRACE 结合使用时,它可以记录信息,例如通过网络发送和接收的标头和正文。要启用窃听,请分别为 HttpServer 和 HttpClient 设置 spring.cloud.gateway.httpserver.wiretap=true 或 spring.cloud.gateway.httpclient.wiretap=true 。

17. Developer Guide 开发者指南

这些是编写网关的一些自定义组件的基本指南。

17.1. Writing Custom Route Predicate Factories 编写自定义路由谓词工厂

为了编写 Route Predicate,您需要将 RoutePredicateFactory 实现为 bean。您可以扩展一个名为 AbstractRoutePredicateFactory 的抽象类。

MyRoutePredicateFactory.java

@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {public MyRoutePredicateFactory() {super(Config.class);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {// grab configuration from Config objectreturn exchange -> {//grab the requestServerHttpRequest 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}}

17.2. Writing Custom GatewayFilter Factories 编写自定义 GatewayFilter 工厂

要编写 GatewayFilter,您必须将 GatewayFilterFactory 实现为 bean。您可以扩展一个名为 AbstractGatewayFilterFactory 的抽象类。以下示例显示了如何执行此操作:

Example 75. PreGatewayFilterFactory.java

@Component
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {public PreGatewayFilterFactory() {super(Config.class);}@Overridepublic GatewayFilter apply(Config config) {// grab configuration from Config objectreturn (exchange, chain) -> {//If you want to build a "pre" filter you need to manipulate the//request before calling chain.filterServerHttpRequest.Builder builder = exchange.getRequest().mutate();//use builder to manipulate the requestreturn chain.filter(exchange.mutate().request(builder.build()).build());};}public static class Config {//Put the configuration properties for your filter here}}

PostGatewayFilterFactory.java

@Component
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {public PostGatewayFilterFactory() {super(Config.class);}@Overridepublic GatewayFilter apply(Config config) {// grab configuration from Config objectreturn (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}}

17.2.1. Naming Custom Filters And References In Configuration 在配置中命名自定义过滤器和引用

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

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

  • 可以创建一个没有 GatewayFilterFactory 后缀的网关过滤器,例如类 AnotherThing。此过滤器可以在配置文件中作为 AnotherThing 引用。这不是受支持的命名约定,并且在将来的版本中可能会删除此语法。请更新过滤器名称以使其符合要求。

17.3. Writing Custom Global Filters 编写自定义全局过滤器

要编写自定义全局过滤器,您必须将 GlobalFilter 接口实现为 bean。这会将过滤器应用于所有请求。 以下示例分别显示了如何设置全局前置和后置过滤器:

@Bean
public GlobalFilter customGlobalFilter() {return (exchange, chain) -> exchange.getPrincipal().map(Principal::getName).defaultIfEmpty("Default User").map(userName -> {//adds header to proxied requestexchange.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 -> {//adds header to responseserverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");return serverWebExchange;}).then();
}

18. Building a Simple Gateway by Using Spring MVC or Webflux 使用 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 并将其转换为传出的。 为不向下游传递的“敏感”标头(默认情况下,cookie 和授权)和“代理”(x-forwarded-*)标头提供一流的支持。

19. Configuration properties配置属性

要查看所有 Spring Cloud Gateway 相关配置属性的列表,请参阅附录 the appendix.。

网关 翻译版本 spring cloud gateway相关推荐

  1. 微服务 API 网关架构演进 Spring Cloud Gateway ShenYu APISIX

    目录 后台服务网关 Spring Cloud Gateway 遇到问题 Apache ShenYu Higress fizz-gateway-community 企业案例 前台流量网关 APISIX ...

  2. 微服务网关Zuul迁移到Spring Cloud Gateway

    https://juejin.im/post/5ba8daa56fb9a05cfe486ebf 背景 在之前的文章中,我们介绍过微服务网关Spring Cloud Netflix Zuul,前段时间有 ...

  3. ws配置 zuul_微服务网关 Spring Cloud Gateway

    1.  为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...

  4. Spring Cloud Gateway(一)为什么用网关、能做什么、为什么选择Gateway、谓词工厂、过滤器配置

    1.为什么用网关?能做什么?为什么选择Gateway? 1.1.为什么用网关 网关api:封装了系统内部架构,为每个客户端提供一个定制的 API.在微服务架构中,服务网关的核心要点是,所有的客户端和消 ...

  5. Spring Cloud(10)——新一代网关Spring Cloud Gateway

    文章目录 Spring Cloud(10)--新一代网关Spring Cloud Gateway 1.背景知识--API网关 2.Spring Cloud Gateway 详细概述 3.Spring ...

  6. springcloud(十一):服务网关 Spring Cloud GateWay 入门

    Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...

  7. Spring Cloud Gateway网关

    Spring Cloud Gateway网关 1. 简介 Spring Cloud Gateway是Spring官网基于Spring 5.0. Spring Boot 2.0.Project Reac ...

  8. Spring Cloud Gateway(过滤器)

    在上一篇文章中,我们了解了 Spring Cloud Gateway 作为网关所具备的基础功能:路由.本篇我们将关注它的另一个功能:过滤器. Spring Cloud Gateway 已经内置了很多实 ...

  9. 基于Nacos配置中心实现Spring Cloud Gateway的动态路由管理

    前面我们了解过了Sentinel 网关流量控制之Spring Cloud Gateway实战,今天带给大家是基于Nacos配置中心实现Spring Cloud Gateway的动态路由管理. 1.为什 ...

最新文章

  1. 转载--httpclient原理和应用
  2. lisp封装成vla函数_Lisp List 和函数式编程 (in Python)
  3. Administer Service Cloud
  4. Java并发编程—无锁互斥机制及CAS原理
  5. iphone如何使用CoreNFC
  6. 基本服务-使用大使网关
  7. 全套学习!mysql2003错误代码
  8. opengl多重纹理映射
  9. vue 递归组件多级_Vue 递归组件构建一个树形菜单
  10. Vector和Arraylist的区别
  11. 记录xmapp升级过程中解决mysql扩展中出现的问题
  12. 计算机竞赛 自主招生,2017年自主招生认可的竞赛汇总
  13. 起步 —— 种一棵树最好的时间是十年前
  14. 好文:练习一万小时成天才?(by同人于野)
  15. matlab 添加子图图案,matplotlib给子图添加图例的方法
  16. Excel如何快速评定考核成绩等级
  17. 【大数据】阿里云大数据专业认证考试
  18. 《夏风》刊发的几组诗词
  19. 『大牛公司机构近期研究报告大合集』第二版
  20. 【一周头条盘点】中国软件网(2018.1.29~2018.2.2)

热门文章

  1. Anaconda创建虚拟环境、配环境变量步骤笔记
  2. 【TeamViewer Host插件】电脑端控制安卓手机(小米)【解决方案】
  3. docker - 端口占用
  4. 与一汽密谈 南汽罗孚点将起航
  5. 关于考博复试PPT的制作
  6. J网页制作之avaScript 简介
  7. 计算机设备 软件总账和明细账,广东省会计从业资格考试《初级会计电算化》实务操作练习题.doc...
  8. 国家4A级旅游风景区安化云台山欢迎您的到来
  9. 基于AutoJs的微博日常任务(转发、关注、评论、发微博、刷微博)
  10. 程序员如何成为一个风一样的男子!?