2.2.1.BUILD-SNAPSHOT
该项目提供了一个在Spring生态系统之上构建的API网关,包括:Spring 5,Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注,例如:安全性,监视/指标和弹性。
1. 如何包括Spring Cloud Gateway
要将Spring Cloud Gateway包含在您的项目中,请使用具有组org.springframework.cloud 和工件ID 的启动器spring-cloud-starter-gateway。有关 使用当前Spring Cloud Release Train设置构建系统的详细信息,请参见Spring Cloud Project页面。
如果包括启动器,但是由于某种原因,您不希望启用网关,请设置spring.cloud.gateway.enabled=false。
术语
- Route:路由网关的基本构建块。它由ID,目标URI,判断集合和过滤器集合定义。如果聚合判断为true,则匹配路由。
- 判断:这是Java 8 Function判断。输入类型是Spring FrameworkServerWebExchange。这使开发人员可以匹配HTTP请求中的所有内容,例如标头或参数。
- Filter:这些是使用特定工厂构建的Spring FrameworkGatewayFilter实例。在此,可以在发送下游请求之前或之后修改请求和响应。
3. 工作原理
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序运行通过特定于请求的筛选器链发送请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前或之后执行逻辑。执行所有“前置”过滤器逻辑,然后发出代理请求。发出代理请求后,将执行“发布”过滤器逻辑。
4. 路由判断工厂
Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些判断都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以合并,也可以通过逻辑合并and。
4.1 后路线判断工厂
After Route Predicate Factory采用一个参数,即日期时间。该判断匹配在当前日期时间之后发生的请求。
application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
此路线与2017年1月20日17:42山区时间(丹佛)之后的所有请求匹配。
4.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]
此路线与2017年1月20日17:42山区时间(丹佛)之前的所有请求匹配。
4.3 路线判断工厂之间
路由判断间工厂之间有两个参数,datetime1和datetime2。该判断匹配在datetime1之后和datetime2之前发生的请求。datetime2参数必须在datetime1之后。
application.yml
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
该路线与2017年1月20日山区时间(丹佛)之后和2017年1月21日17:42山区时间(丹佛)之后的所有请求匹配。这对于维护时段可能很有用。
4.4 .Cookie路线判断工厂
Cookie Route Predicate Factory采用两个参数,即cookie名称和正则表达式。该判断匹配具有给定名称的cookie,并且值匹配正则表达式。
application.yml
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
此路由与请求匹配,并具有一个名为chocolatewho的值与ch.p正则表达式匹配的cookie 。
4.5 标头路由判断工厂
标头路由判断工厂采用两个参数,标头名称和正则表达式。该判断与具有给定名称的标头匹配,并且值与正则表达式匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求具有名为X-Request-Id其值与\d+正则表达式匹配(具有一个或多个数字的值)的标头,则此路由匹配。
4.6 主机路由判断工厂
主机路由判断工厂采用一个参数:主机名模式列表。该模式是带有.作为分隔符的Ant样式的模式。判断与Host匹配模式的标头匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
还支持URI模板变量{sub}.myhost.org。
如果请求的Host标头中包含值www.somehost.orgor beta.somehost.org或,则此路由将匹配www.anotherhost.org。
该判断提取URI模板变量(sub如上例中定义的那样)作为名称和值的映射,并ServerWebExchange.getAttributes()使用中定义的键将其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。这些值可供GatewayFilter工厂使用。
4.7 方法路线判断工厂
方法路由判断工厂使用一个参数:要匹配的HTTP方法。
application.yml
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET
如果request方法为,则此路由将匹配GET
。
4.8 路径路线判断工厂
路径路由判断工厂具有两个参数:弹簧PathMatcher模式列表和的可选标志matchOptionalTrailingSeparator。
application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Path=/foo/{segment},/bar/{segment}
如果请求路径是,例如这条路线将匹配:/foo/1或/foo/bar或/bar/baz。
该判断提取URI模板变量(segment如上例中定义的那样)作为名称和值的映射,并ServerWebExchange.getAttributes()使用中定义的键将其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。这些值可供GatewayFilter工厂使用。
可以使用实用程序方法来简化对这些变量的访问
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
4.9 查询路由判断工厂
查询路由判断工厂采用两个参数:required param和optional regexp。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=baz
如果请求包含baz查询参数,则此路由将匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=foo, ba.
如果请求包含一个foo查询参数,其值与ba.regexp 匹配,则此路由将匹配,bar并且baz将匹配。
4.10 RemoteAddr路由判断工厂
RemoteAddr路由判断工厂采用CIDR表示法(IPv4或IPv6)字符串的列表(最小大小为1),例如192.168.0.1/16(其中192.168.0.1IP地址16为子网掩码)。
application.yml
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址为,则此路由将匹配192.168.1.10。
4.10 重量路线判断工厂
权重路由判断工厂采用两个参数组和权重。权重是按组计算的。
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
这条路线会将约80%的流量转发至weighthigh.org,并将约20%的流量转发至weightlow.org。
4.11 .1 修改远程地址的解析方式
默认情况下,RemoteAddr路由判断工厂使用传入请求中的远程地址。如果Spring Cloud Gateway位于代理层后面,则此地址可能与实际的客户端IP地址不匹配。
您可以通过设置custom来定制解析远程地址的方式RemoteAddressResolver
。 Spring Cloud Gateway 来与基于脱一个非默认的远程地址解析器的X -转发,对于头,XForwardedRemoteAddressResolver
。
XForwardedRemoteAddressResolver
有两种静态构造方法,它们采用不同的安全性方法:
XForwardedRemoteAddressResolver::trustAll
返回RemoteAddressResolver
,该地址始终采用在X-Forwarded-For
标头中找到的第一个IP地址。这种方法容易受到欺骗的攻击,因为恶意客户端可能会为其设置一个初始值,X-Forwarded-For
解析器会接受该初始值。
XForwardedRemoteAddressResolver::maxTrustedIndex
取得与Spring Cloud Gateway前面运行的受信任基础架构数量相关的索引。例如,如果只能通过HAProxy访问Spring Cloud Gateway,则应使用值1。如果在访问Spring Cloud Gateway之前需要两跳可信基础架构,则应使用值2。
给定以下标头值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
maxTrustedIndex
下面的值将产生以下远程地址。
maxTrustedIndex | 结果 |
---|---|
[ Integer.MIN_VALUE ,0] | (IllegalArgumentException 在初始化期间无效) |
1个 | 0.0.0.3 |
2 | 0.0.0.2 |
3 | 0.0.0.1 |
[4,Integer.MAX_VALUE ] | 0.0.0.1 |
使用Java配置:
网关配置文件
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")
)
5 GatewayFilter工厂
路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器适用于特定路由。Spring Cloud Gateway包括许多内置的GatewayFilter工厂。
注意有关如何使用以下任何过滤器的更多详细示例,请查看单元测试。
5.1 AddRequestHeader GatewayFilter工厂
AddRequestHeader GatewayFilter工厂采用名称和值参数。
application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
这会将X-Request-Foo:Bar
标头添加到所有匹配请求的下游请求的标头中。
AddRequestHeader知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。
application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/foo/{segment}
filters:
- AddRequestHeader=X-Request-Foo, Bar-{segment}
5.2 AddRequestParameter GatewayFilter工厂
AddRequestParameter GatewayFilter工厂采用名称和值参数。
application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=foo, bar
这将添加foo=bar
到所有匹配请求的下游请求的查询字符串中。
AddRequestParameter知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。
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}
5.3 AddResponseHeader GatewayFilter工厂
AddResponseHeader GatewayFilter工厂采用名称和值参数。
application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Foo, Bar
这会将X-Response-Foo:Bar
标头添加到所有匹配请求的下游响应的标头中。
AddResponseHeader知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。
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}
5.4 DedupeResponseHeader GatewayFilter工厂
DedupeResponseHeader GatewayFilter工厂采用一个name
参数和一个可选strategy
参数。name
可以包含标题名称列表,以空格分隔。
application.yml
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
如果网关CORS逻辑和下游逻辑都添加了重复的值Access-Control-Allow-Credentials
和Access-Control-Allow-Origin
响应标头,则这将删除它们。
DedupeResponseHeader过滤器还接受可选strategy
参数。可接受的值为RETAIN_FIRST
(默认值)RETAIN_LAST
,和RETAIN_UNIQUE
。
5.5Hystrix GatewayFilter工厂
Hystrix是Netflix的一个库,用于实现断路器模式。Hystrix GatewayFilter允许您将断路器引入网关路由,保护您的服务免受级联故障的影响,并允许您在下游故障的情况下提供后备响应。
要在项目中启用Hystrix GatewayFilters,请spring-cloud-starter-netflix-hystrix
从Spring Cloud Netflix添加依赖项。
Hystrix GatewayFilter工厂需要一个name
参数,它是的名称HystrixCommand
。
application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
这会将其余的过滤器包装在HystrixCommand
带有命令名的中myCommandName
。
Hystrix过滤器还可以接受可选fallbackUri
参数。当前,仅forward:
支持计划的URI。如果调用了后备,则请求将被转发到与URI相匹配的控制器。
application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
/incaseoffailureusethis
调用Hystrix后备时,它将转发到URI。请注意,此示例还通过lb
目标URI 上的前缀演示了(可选)Spring Cloud Netflix Ribbon负载平衡。
主要方案是对fallbackUri
网关应用程序中的内部控制器或处理程序使用。但是,也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:
application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在此示例中,fallback
网关应用程序中没有终结点或处理程序,但是另一个应用程序中有一个终结点或处理程序,在下注册localhost:9994
。
如果将请求转发给后备,则Hystrix网关过滤器还会提供Throwable
引起请求的。它已ServerWebExchange
作为 ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR
属性添加到,可以在网关应用程序中处理后备时使用。
对于外部控制器/处理程序方案,可以添加带有异常详细信息的标头。您可以在FallbackHeaders GatewayFilter Factory部分中找到有关它的更多信息。
Hystrix设置(例如超时)可以使用全局默认值配置,也可以使用Hystrix Wiki上说明的应用程序属性在逐条路由的基础上进行配置。
要为上述示例路由设置5秒超时,将使用以下配置:
application.yml
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
5.6 Spring Cloud CircuitBreaker GatewayFilter工厂
Spring Cloud CircuitBreaker过滤器工厂利用Spring Cloud CircuitBreaker API将网关路由包装在断路器中。Spring Cloud CircuitBreaker支持可与Spring Cloud Gateway一起使用的两个库Hystrix和Resilience4J。由于Netflix将Hystrix置于仅维护模式,因此我们建议您使用Resilience4J。
要启用Spring Cloud CircuitBreaker过滤器,您将需要放置spring-cloud-starter-circuitbreaker-reactor-resilience4j或 spring-cloud-starter-netflix-hystrix放置在类路径上。
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参阅所使用的基础断路器实现的配置。
Spring Cloud CircuitBreaker过滤器也可以接受可选fallbackUri
参数。当前,仅forward:
支持计划的URI。如果调用了后备,则请求将被转发到与URI相匹配的控制器。
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
应用程序
@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。请注意,此示例还通过lb
目标URI 上的前缀演示了(可选)Spring Cloud Netflix Ribbon负载平衡。
主要方案是对fallbackUri
网关应用程序中的内部控制器或处理程序使用。但是,也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:
application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在此示例中,fallback
网关应用程序中没有终结点或处理程序,但是另一个应用程序中有一个终结点或处理程序,在下注册localhost:9994
。
如果将请求转发给后备,则Spring Cloud CircuitBreaker网关过滤器还会提供Throwable
引起请求的。它已ServerWebExchange
作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR
属性添加到,可以在网关应用程序中处理后备时使用。
对于外部控制器/处理程序方案,可以添加带有异常详细信息的标头。您可以在FallbackHeaders GatewayFilter Factory部分中找到有关它的更多信息。
5.7 FallbackHeaders GatewayFilter工厂
该FallbackHeaders工厂可以让你在转发到请求的头部添加Hystrix or Spring Cloud CircuitBreaker执行异常的详细信息fallbackUri在以下情况下在外部应用程序,如:
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
通过设置下面列出的参数的值及其默认值,可以在配置中覆盖标头的名称:
executionExceptionTypeHeaderName
("Execution-Exception-Type"
)executionExceptionMessageHeaderName
("Execution-Exception-Message"
)rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
)rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
有关circuit beakers 和网关的更多信息,请参见Hystrix GatewayFilter Factory部分或 Spring Cloud CircuitBreaker Factory部分。
5.8。MapRequestHeader GatewayFilter工厂
MapRequestHeader GatewayFilter工厂采用’fromHeader’和’toHeader’参数。它创建一个新的命名标头(toHeader),并从传入的HTTP请求中从现有的命名标头(fromHeader)中提取值。如果输入标头不存在,则过滤器不起作用。如果新的命名标头已经存在,则其值将使用新值进行扩充。
application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Bar, X-Request-Foo
这会将X-Request-Foo:<values>
标头添加到下游请求的标头中,其中包含来自传入的HTTP请求Bar
标头的更新值。
5.9 PrefixPath GatewayFilter工厂
PrefixPath GatewayFilter工厂采用单个prefix参数。
application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
这将/mypath
作为所有匹配请求的路径的前缀。因此,对的请求/hello
将发送给/mypath/hello
。
5.10PreserveHostHeader GatewayFilter工厂
PreserveHostHeader GatewayFilter工厂没有参数。此过滤器设置请求属性,路由过滤器将检查该请求属性,以确定是否应发送原始主机头,而不是由HTTP客户端确定的主机头。
application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
5.11 RequestRateLimiter GatewayFilter工厂
RequestRateLimiter GatewayFilter Factory使用一种RateLimiter
实现来确定是否允许继续当前请求。如果不是,HTTP 429 - Too Many Requests
则返回状态(默认)。
此过滤器采用一个可选keyResolver
参数和特定于速率限制器的参数(请参见下文)。
keyResolver
是实现KeyResolver
接口的bean 。在配置中,使用SpEL按名称引用bean。#{@myKeyResolver}
是SpEL表达式,它引用名称为的bean myKeyResolver
。
KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
该KeyResolver
接口允许可插拔策略派生用于限制请求的密钥。在未来的里程碑中,将有一些KeyResolver
实现。
的默认实现KeyResolver
是,PrincipalNameKeyResolver
它Principal
从ServerWebExchange
和调用检索Principal.getName()
。
默认情况下,如果KeyResolver
找不到密钥,则请求将被拒绝。可以使用spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
(true或false)和spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
属性来调整此行为。
application.properties
#无效的快捷方式配置
spring.cloud.gateway.routes [0] .filters [0] = RequestRateLimiter = 2,2,#{@ userkeyresolver}
5.11.1。Redis RateLimiter
redis实现基于Stripe所做的工作。它需要使用spring-boot-starter-data-redis-reactive
Spring Boot启动器。
使用的算法是令牌桶算法。
该redis-rate-limiter.replenishRate
是多么的每秒许多请求你希望用户被允许做,没有任何下降的请求。这是令牌桶被填充的速率。
的redis-rate-limiter.burstCapacity
是允许用户在一个单一的第二做请求的最大数目。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。
通过在replenishRate
和中设置相同的值,可以达到稳定的速率burstCapacity
。设置burstCapacity
大于可以允许临时爆发replenishRate
。在这种情况下,速率限制器需要在突发之间间隔一段时间(根据replenishRate
),因为2个连续的突发将导致请求丢失(HTTP 429 - Too Many Requests
)。
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
配置文件
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户10的请求速率限制。允许20个突发,但是下一秒只有10个请求可用。这KeyResolver
是一个简单的获取user
请求参数的参数(注意:不建议在生产中使用)。
速率限制器也可以定义为实现RateLimiter
接口的Bean 。在配置中,使用SpEL按名称引用bean。#{@myRateLimiter}
是SpEL表达式,它引用名称为的bean myRateLimiter
。
application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
5.12 重定向到GatewayFilter工厂
RedirectTo GatewayFilter工厂采用status
和url
参数。状态应该是300系列重定向http代码,例如301。URL应该是有效的URL。这将是Location
标题的值。
application.yml
RedirectTo GatewayFilter工厂采用status和url参数。状态应该是300系列重定向http代码,例如301。URL应该是有效的URL。这将是Location标题的值。
application.yml
这将发送带有Location:https://acme.org
标头的状态302 以执行重定向。
5.13。RemoveHopByHopHeadersFilter GatewayFilter工厂
RemoveHopByHopHeadersFilter GatewayFilter工厂从转发的请求中删除标头。被删除的头的默认列表来自IETF。
默认删除的标题是:
- 连接
- 活着
- 代理验证
- 代理授权
- TE
- 预告片
- 传输编码
- 升级
要更改此设置,请将spring.cloud.gateway.filter.remove-non-proxy-headers.headers
属性设置为要删除的标题名称列表。
5.14。RemoveRequestHeader GatewayFilter工厂
RemoveRequestHeader GatewayFilter工厂采用一个name
参数。它是要删除的标题的名称。
application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这将删除X-Request-Foo
标头,然后再将其发送到下游。
5.15。RemoveResponseHeader GatewayFilter工厂
RemoveResponseHeader GatewayFilter工厂采用一个name
参数。它是要删除的标题的名称。
application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
这将从X-Response-Foo
响应中删除标头,然后将其返回到网关客户端。
要删除任何类型的敏感标头,应为可能需要的任何路由配置此过滤器。另外,您可以使用一次配置此过滤器,spring.cloud.gateway.default-filters
并将其应用于所有路由。
6.全局过滤器
该GlobalFilter
接口具有与相同的签名GatewayFilter
。这些是特殊过滤器,有条件地应用于所有路由。(此界面和用法可能会在将来的里程碑中更改)。
6.1。全局过滤器和GatewayFilter的组合订购
当请求进入(并与路由匹配)时,过滤Web处理程序会将的所有实例GlobalFilter
和所有特定GatewayFilter
于路由的实例添加到过滤器链中。该组合的过滤器链按org.springframework.core.Ordered
接口排序,可以通过实现该getOrder()
方法进行设置。
由于Spring Cloud Gateway区分了执行过滤器逻辑的“前”阶段和“后”阶段(请参阅:工作原理),因此优先级最高的过滤器将在“前”阶段中处于第一个阶段,而在“后”阶段中处于最后一个阶段“-相。
ExampleConfiguration.java
@Bean
public GlobalFilter customFilter() {
return 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;
}
}
6.2。正向路由过滤器
将ForwardRoutingFilter
在交换属性查找一个URI ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
。如果url有一个forward
方案(即forward:///localendpoint
),它将使用Spring DispatcherHandler
处理请求。请求URL的路径部分将被转发URL中的路径覆盖。未经修改的原始url将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。
6.3。LoadBalancerClient筛选器
将LoadBalancerClientFilter
在交换属性查找一个URI ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
。如果url有一个lb
方案(即lb://myservice
),它将使用Spring Cloud LoadBalancerClient
将名称(myservice
在前面的示例中)解析为实际的主机和端口,并在同一属性中替换URI。未经修改的原始url将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。过滤器还将在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性中查找是否相等lb
,然后应用相同的规则。
application.yml
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
6.4。ReactiveLoadBalancerClientFilter
将ReactiveLoadBalancerClientFilter
在交换属性查找一个URI ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
。如果url有一个lb
方案(即lb://myservice
),它将使用Spring Cloud ReactorLoadBalancer
将名称(myservice
在前面的示例中)解析为实际的主机和端口,并在同一属性中替换URI。未经修改的原始url将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。过滤器还将在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性中查找是否相等 lb
,然后应用相同的规则。
application.yml
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
默认情况下,当找不到服务实例时ReactorLoadBalancer
,503
将返回a。您可以404
通过设置将网关配置为返回spring.cloud.gateway.loadbalancer.use404=true
。
从返回 的isSecure
值将覆盖对网关的请求中指定的方案。例如,如果请求通过网关进入网关, 但指示该请求不安全,则将通过下游请求 。相反的情况也可以适用。但是,如果在“网关”配置中为路由指定了该前缀,则将删除前缀,并且从路由URL生成的方案将覆盖该配置。 ServiceInstance``ReactiveLoadBalancerClientFilter``HTTPS``ServiceInstance``HTTP``GATEWAY_SCHEME_PREFIX_ATTR``ServiceInstance
6.5。网络路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的URL 具有http
或https
方案,则将运行Netty路由筛选器。它使用Netty HttpClient
发出下游代理请求。响应将放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange属性中,以供以后的过滤器使用。(有一个WebClientHttpRoutingFilter
执行相同功能的实验,但不需要净值)
6.6。净写响应过滤器
NettyWriteResponseFilter,如果有一个运行的Netty HttpClientResponse在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交换属性。它在所有其他筛选器完成后运行,并将代理响应写回到网关客户端响应。(有一个WebClientWriteResponseFilter执行相同功能的实验,但不需要净值)
6.7。RouteToRequestUrl过滤器
RouteToRequestUrlFilter,如果有一个运行
Route中的对象
ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR交换属性。它基于请求URI创建一个新URI,但使用
Route对象的URI属性进行更新。新的URI放置在
ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR`exchange属性中。
如果URI具有方案前缀(例如)lb:ws://serviceid
,则将lb
方案从URI中剥离,并放入中以ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
供稍后在过滤器链中使用。
6.8。Websocket路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中的URL 具有ws或wss方案,则Websocket路由筛选器将运行。它使用Spring Web Socket基础结构向下游转发Websocket请求。
的WebSockets可以是负载平衡用前缀的URI lb,如lb:ws://serviceid。
如果您将SockJS用作常规http的后备,则应配置常规HTTP路由以及Websocket路由。
application.yml
spring:
cloud:
gateway:
routes:
# SockJS route
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# Normwal Websocket route
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**
6.9。网关指标过滤器
要启用网关度量标准,请添加spring-boot-starter-actuator作为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled
未设置为,网关度量过滤器就会运行false
。此过滤器添加一个带有以下标记的名为“ gateway.requests”的计时器度量标准:
routeId
:路线IDrouteUri
:API将被路由到的URIoutcome
:按HttpStatus.Series分类的结果status
:请求返回给客户端的Http状态httpStatusCode
:请求返回给客户端的Http状态httpMethod
:用于请求的Http方法
然后可以从这些指标中删除这些指标,/actuator/metrics/gateway.requests
并可以将它们轻松地与Prometheus集成以创建Grafana 仪表板。
6.10。将交换标记为已路由
网关路由完成后,ServerWebExchange
它将通过添加gatewayAlreadyRouted
到交换属性来将该交换标记为“已路由” 。将请求标记为已路由后,其他路由筛选器将不会再次路由请求,实质上会跳过该筛选器。您可以使用方便的方法将交换标记为已路由或检查交换是否已路由。
ServerWebExchangeUtils.isAlreadyRouted
接受一个ServerWebExchange
对象并检查它是否已被“路由”ServerWebExchangeUtils.setAlreadyRouted
接受一个ServerWebExchange
对象并将其标记为“已路由”
7. TLS / SSL
网关可以通过遵循常规的Spring服务器配置来侦听https上的请求。例:
application.yml
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
网关路由可以同时路由到http和https后端。如果路由到https后端,则可以使用以下配置将网关配置为信任所有下游证书:
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
使用不安全的信任管理器不适用于生产。对于生产部署,可以使用以下配置为网关配置一组可以信任的已知证书:
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
如果未为Spring Cloud Gateway提供受信任的证书,则使用默认的信任存储(可以用系统属性javax.net.ssl.trustStore覆盖)。
7.1。TLS握手
网关维护用于路由到后端的客户端池。通过https进行通信时,客户端会启动TLS握手。许多超时与此握手相关联。可以配置以下超时(显示默认值):
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0
8.配置
Spring Cloud Gateway的配置由RouteDefinitionLocator的集合驱动。
RouteDefinitionLocator.java
public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}
默认情况下,PropertiesRouteDefinitionLocator
使用Spring Boot的@ConfigurationProperties
机制加载属性。
上面的所有配置示例都使用一种快捷方式符号,该快捷方式符号使用位置参数而不是命名参数。以下两个示例是等效的:
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
对于网关的某些用法,属性将是足够的,但是某些生产用例将受益于从外部源(例如数据库)加载配置。未来的里程碑版本将RouteDefinitionLocator
基于Spring数据存储库实现,例如:Redis,MongoDB和Cassandra。
9.路由元数据配置
可以使用元数据为每个路由配置其他参数:
application.yml
spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1
可以从交换中获取所有元数据属性:
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);
9.1。流利的Java Routes API
为了在Java中进行简单的配置,在RouteLocatorBuilder
bean中定义了一个流畅的API 。
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 定义的谓词使用逻辑组合and
。通过使用流利的Java API,你可以使用and()
,or()
并且negate()
对运营Predicate
类。
9.2。DiscoveryClient路由定义定位器
可以将网关配置为基于在DiscoveryClient
兼容服务注册表中注册的服务来创建路由。
要启用此功能,请设置spring.cloud.gateway.discovery.locator.enabled=true
并确保DiscoveryClient
实现在类路径上并已启用(例如Netflix Eureka,Consul或Zookeeper)。
9.2.1。为DiscoveryClient路由配置谓词和过滤器
默认情况下,网关为通过创建的路由定义单个谓词和过滤器DiscoveryClient
。
默认谓词是使用模式定义的路径谓词/serviceId/**
,其中serviceId
是来自的服务ID DiscoveryClient
。
默认的过滤器是带有正则表达式/serviceId/(?<remaining>.*)
和替换的 重写路径过滤器/${remaining}
。这只是在将请求发送到下游之前从路径中剥离服务ID。
如果您想自定义DiscoveryClient
路线使用的谓词和/或过滤器,可以通过设置spring.cloud.gateway.discovery.locator.predicates[x]
和来实现spring.cloud.gateway.discovery.locator.filters[y]
。这样做时,如果要保留该功能,则需要确保在上面包含默认谓词和过滤器。以下是此示例的示例。
application.properties
spring.cloud.gateway.discovery.locator.predicates [0]。名称:路径
spring.cloud.gateway.discovery.locator.predicates [0] .args [pattern]:“'/'+ serviceId +'/ **'”
spring.cloud.gateway.discovery.locator.predicates [1]。名称:主机
spring.cloud.gateway.discovery.locator.predicates [1] .args [pattern]:“'**。foo.com'”
spring.cloud.gateway.discovery.locator.filters [0]。名称:Hystrix
spring.cloud.gateway.discovery.locator.filters [0] .args [name]:serviceId
spring.cloud.gateway.discovery.locator.filters [1]。名称:RewritePath
spring.cloud.gateway.discovery.locator.filters [1] .args [regexp]:“'/'+ serviceId +'/(?<remaining>.*)'”
spring.cloud.gateway.discovery.locator.filters [1] .args [replacement]:“'/ $ {remaining}'”
10. Reactor Netty访问日志
要启用Reactor Netty访问日志,请设置-Dreactor.netty.http.server.accessLogEnabled=true
。(它必须是Java System属性,而不是Spring Boot属性)。
日志系统可以配置为具有单独的访问日志文件。以下是示例登录配置:
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>
11. CORS配置
可以将网关配置为控制CORS行为。“全局” CORS配置是URL模式到Spring FrameworkCorsConfiguration
的映射。
application.yml
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
在上面的示例中,将从docs.spring.io发出的所有GET请求路径的请求中允许CORS请求。
要为未被某些网关路由谓词处理的请求提供相同的CORS配置,请将属性设置spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping
为true。当尝试支持CORS预检请求并且您的路由谓词未评估为true时,此方法很有用,因为http方法为options
。