6. 路由filter
过滤器允许以某种方式修改传入的HTTP请求或返回的HTTP响应。过滤器的作用域是某些特定路由。Spring Cloud Gateway包括许多内置的 Filter工厂。
有关如何使用以下任何过滤器的更详细示例,请查看 unit tests. |
6.1 添加请求Header
为请求添加header, 采用一对名称和值作为参数
Example 13. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
"X-Request-red:blue"会被添加到路由的请求header中。
AddRequestHeader 可以和URI变量一起用,如:
Example 14. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
6.2 添加请求参数
为请求添加参数,采用一对名称和值作为参数
Example 15. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
对于所有匹配的请求,这将向下游请求添加red=blue
查询字符串
AddRequestParameter也可以和path或host断言 的URI变量结合使用,如:
Example 16. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
6.3 添加响应Header
为响应添加header,采用一对名称和值作为参数
Example 17. application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
对于所有匹配的请求,这会将x-response-Red:Blue
头添加到下游响应的header中.
同样也可以和URI变量一起使用
6.4. 删除重复header
删除响应头重复值
。
如果在代码和代理(如nginx)中都有添加header的配置时,有可能会重复添加,引发异常。
DedupeResponseHeader GatewayFilter Factory采用名称参数和可选策略参数。name可以包含标题名称列表,空格分隔。
Example 19. 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过滤器还接受可选的策略参数。接受的值为RETAIN_FIRST(默认值),RETAIN_LAST和RETAIN_UNIQUE。
6.5 Hystrix 过滤器
hystrix网关断路器
Hystrix 是Netflix开源的断路器组件。Hystrix GatewayFilter允许你向网关路由引入断路器,保护你的服务不受级联故障的影响,并允许你在下游故障时提供fallback响应。
注意
Hystrix已经进入维护期,我们建议你使用基于Resilience4J的Spring Cloud CircuitBreaker Gateway Filter ,
在以后的版本中Hystrix会被移除。
Hystrix 是Netflix开源的断路器组件。Hystrix GatewayFilter允许你向网关路由引入断路器,保护你的服务不受级联故障的影响,并允许你在下游故障时提供fallback响应。
要在项目中启用Hystrix网关过滤器,需要添加对 spring-cloud-starter-netflix-hystrix
的依赖 Spring Cloud Netflix.
Hystrix GatewayFilter Factory 需要一个name参数,即HystrixCommand
的名称。
Example 20. application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
这将剩余的过滤器包装在命令名为“myCommandName”的HystrixCommand
中。
hystrix过滤器还可以接受可选的fallbackUri
参数。目前,仅支持forward:
预设的URI,如果调用fallback,则请求将转发到与URI匹配的控制器。
Example 21. 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
当调用hystrix fallback时,这将转发到/incaseoffailureusethis
uri。注意,这个示例还演示了(可选)通过目标URI上的'lb`前缀,使用Spring Cloud Netflix Ribbon 客户端负载均衡。
主要场景是使用fallbackUri
到网关应用程序中的内部控制器或处理程序。但是,也可以将请求重新路由到外部应用程序中的控制器或处理程序,如:
Example 22. 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
在本例中,gateway应用程序中没有 fallback
实现,但是另一个应用程序中有一个接口实现,注册为“http://localhost:9994”。
在将请求转发到fallback的情况下,Hystrix Gateway过滤还支持直接抛出Throwable
。它被作为ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR
属性添加到ServerWebExchange
中,可以在处理网关应用程序中的fallback时使用。
对于外部控制器/处理程序方案,可以添加带有异常详细信息的header。可以在 FallbackHeaders GatewayFilter Factory section中找到有关它的更多信息。
hystrix配置参数(如 timeouts)可以使用全局默认值配置,也可以使用Hystrix wiki中所述属性进行配置
要为上面的示例路由设置5秒超时,将使用以下配置:
Example 23. application.yml
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
6.6. Spring Cloud CircuitBreaker
网关断路器
Spring Cloud CircuitBreaker 支持使用 Hystrix 和 Resilience4J 两个库实现,但由于Hystrix已经进入维护模式, 我们推荐使用Resilience4J。
启用Spring Cloud CircuitBreaker filter 首先引入对应的依赖:
spring-cloud-starter-circuitbreaker-reactor-resilience4j
或
spring-cloud-starter-netflix-hystrix
然后添加配置:
Example 24. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
详细配置项可以查看对应的说明文档:
The Spring Cloud CircuitBreaker filter 还可以使用 fallbackUri 参数,但 目前只能和 forward: 搭配使用
; fallback被触发时,请用会被转发到对应的URI,配置如下:
Example 25. application.yml
mple 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
- 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();
}
例子中fallback同时会把请求转发到 /inCaseofFailureUseThis,
RewritePath配置会把地址由 /consumingServiceEndpoint 重写为 /backingServiceEndpoint 。 同时,例子中也使用了 lb 前缀实现负载均衡。
上面的例子是把请求转发到应用内的controller或handler, 但是 fallbackUri 也支持把请求转发到应用外的地址,如:
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
这个例子把请求转发到 地址为 localhost:9994 的另一个应用
在fallback转发的请求中, 可以通过 ServerWebExchange 中的 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性
获取到对应的 Throwable , 更多的异常信息见下一节。
6.7. FallbackHeaders
FallbackHeaders
允许在转发到外部应用程序中的FallbackUri
的请求的header中添加Hystrix或 Spring Cloud CircuitBreake异常详细信息,如下所示:
Example 28. 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
在本例中,在发生异常后,请求将被circuit breaker转发到 localhost:9994
应用程序中的 fallback
终端或程序。异常类型、消息和(如果有)根cause exception类型和消息,将由FallbackHeaders
filter添加到该请求的头中。
下面列出参数值及其默认值,可以在配置中覆盖headers的名称:
executionExceptionTypeHeaderName
("Execution-Exception-Type"
)executionExceptionMessageHeaderName
("Execution-Exception-Message"
)rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
)rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
更多信息查看:Hystrix GatewayFilter Factory section 或 Spring Cloud CircuitBreaker Factory section.
6.8. 修改请求header名称
可以修改header的名称,需要 fromHeader
(原header) 和 toHeader(
新header)两个参数。如果原header不存在,则不会有任何效果。如果新header已经存在,则会被覆盖。
Example 29. application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
header Blue 名称会被修改为X-Request-Red
6.9. 添加url前缀
可以给请求地址添加前缀。如:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
前缀/mypath会添加到所有匹配到的请求地址中。因此 /hello 会发送到 /mypath/hello.
6.10. Host header保护
保存host header。
该filter没有参数。设置了该Filter后,GatewayFilter将不使用由HTTP客户端设置的host header ,而是发送原始host header 。
Example 31. application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.11. 限流
用户限流器,默认根据登录账号限制请求速率。
RequestRateLimiter使用RateLimiter
的实现决定是否允许继续执行当前请求。如果不允许继续执行,则返回HTTP 429 - Too Many Requests
(默认情况下)。
这个过滤器可以配置一个可选的keyResolver
参数和rate limiter参数(见下文)。
keyResolver
是 KeyResolver
接口的实现类.在配置中,按名称使用SpEL引用bean。#{@myKeyResolver}
是引用名为'myKeyResolver'的bean的SpEL表达式。
SpEL用法可以查看文章 SpEL 在注解中的使用
Example 32. KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
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。以下示例无效 |
6.11.1. Redis RateLimiter
Redis的实现基于 Stripe。它需要使用 spring-boot-starter-data-redis-reactive
Spring Boot starter。
使用的算法是 令牌桶算法 , 点击查看。
redis-rate-limiter.replenishRate
是你允许用户每秒执行多少请求,而不丢弃任何请求。这是令牌桶的填充速率。
redis-rate-limiter.burstCapacity是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以保存的令牌数。将此值设置为零将阻止所有请求。
redis-rate-limiter.requestedTokens 是每个请求消耗多少个令牌,默认是1.
稳定速率是通过在replenishRate
(补充令牌速度) 和 burstCapacity
(令牌桶容量)中设置相同的值来实现的。可通过设置burstCapacity
高于replenishRate
来允许临时突发流浪。在这种情况下,限流器需要在两次突发之间留出一段时间(根据replenishRate
),因为连续两次突发将导致请求丢失 (HTTP 429 - Too Many Requests
).。
要限制每秒一个请求,可以将replenishRate设置为目标请求数,requestedTokens设置目标的时间秒数,burstCapacity为replenishRate * requestedTokens。如:设置replenishRate=1
, requestedTokens=60
和 burstCapacity=60,就是限制每分钟1个请求。
Example 34. application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
java KeyResolver配置:
Example 35. Config.java
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户10个请求的限制。允许20个突发,但下一秒只有10个请求可用。KeyResolver
是一个简单的获取user
请求参数的例子(注意:不建议用于生产)。
限流器也可以自定义为实现RateLimiter
接口的 bean。在配置中,按名称使用SpEL引用bean。#{@myRateLimiter}
是引用名为'myRateLimiter'的bean的SpEL表达式。下面的例子中的KeyResolver是前面定义的。
Example 36. application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.12 重定向
该过滤器有一个 status
和一个 url
参数。status是300类重定向HTTP代码,如301。该URL应为有效的URL,这将是 Location
header的值。
Example 37. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送一个302状态码和一个Location:http://acme.org
header来执行重定向。
如果是重定向到相对地址,应该使用 no://op 作为uri值。
spring:
cloud:
gateway:
routes:
- id: jwt_rate_limiting
predicates:
- Path=/login/oauth2/code/login-client
filters:
- RedirectTo=302, /login/oauth2/code/login-client
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 2
redis-rate-limiter.burstCapacity: 2
uri: no://op
6.13 删除请求header
指定要删除的header名称即可
Example 38. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
header X-Request-Foo会被移除,然后下发。
6.14 删除响应header
RemoveResponseHeader 指定要删除的header名称,对应的header会被删除。
Example 39. application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
返回给客户端前,header X-Response-Foo会被删除。
对于一些敏感的header,你可能会希望对所有的路由进行一次性配置,可以通过spring.cloud.gateway.default-filters实现:
spring:
cloud:
gateway:
default-filters:
- RemoveResponseHeader=X-Response-Foo
- AddRequestHeader=X-Request-Name, Value
- AddRequestParameter=name, value
Spring Cloud Gateway 2.2.3 官方使用说明(1)--路由
Spring Cloud Gateway 2.2.3 官方使用说明(2)-- 路由filter(上)
Spring Cloud Gateway 2.2.3 官方使用说明(2)-- 路由filter(下)
Spring Cloud Gateway 2.2.3 官方使用说明(3)-- Global filter
Spring Cloud Gateway 2.2.3 官方使用说明(4)-- HttpHeader Filters
Spring Cloud Gateway 2.2.3 使用说明(5)-- TLS 和 SSL
Spring Cloud Gateway 2.2.3 使用说明(6)-- 其它配置