115. GatewayFilter 工厂

Route 过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 Route 过滤器的范围限定为特定的 route。 Spring Cloud Gateway 包含许多 built-in GatewayFilter 工厂。

注意有关如何使用以下任何过滤器的更多详细示例,请查看单元测试

115.1 AddRequestHeader GatewayFilter Factory

AddRequestHeader GatewayFilter Factory 采用 name 和 value 参数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar

这将为所有匹配的请求将X-Request-Foo:Bar标头添加到下游请求的 headers。

115.2 AddRequestParameter GatewayFilter Factory

AddRequestParameter GatewayFilter Factory 采用 name 和 value 参数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: http://example.org
        filters:
        - AddRequestParameter=foo, bar

这将为所有匹配的请求将foo=bar添加到下游请求的查询 string。

115.3 AddResponseHeader GatewayFilter Factory

AddResponseHeader GatewayFilter Factory 采用 name 和 value 参数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://example.org
        filters:
        - AddResponseHeader=X-Response-Foo, Bar

这将为所有匹配的请求将X-Response-Foo:Bar标头添加到下游响应的 headers。

115.4 Hystrix GatewayFilter Factory

Hystrix是来自 Netflix 的 library,它实现了断路器 pattern。 Hystrix GatewayFilter 允许您将断路器引入网关 routes,保护您的服务免受级联故障的影响,并允许您在下游故障发生时提供回退响应。

要在项目中启用 Hystrix GatewayFilters,请从Spring Cloud Netflix添加对spring-cloud-starter-netflix-hystrix的依赖关系。

Hystrix GatewayFilter Factory 需要一个name参数,即HystrixCommand的 name。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: http://example.org
        filters:
        - Hystrix=myCommandName

这将使用 name myCommandName命令将剩余的过滤器包装在HystrixCommand中。

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

当调用 Hystrix 回退时,这将转发到/incaseoffailureusethis URI。请注意,此 example 还通过目标 URI 上的lb前缀演示(可选)Spring Cloud Netflix Ribbon load-balancing。

Hystrix 设置(例如超时)可以使用 global 默认值配置,也可以使用 application properties 基于 route 配置,如Hystrix wiki所述。

要为上面的 example route 设置 5 秒超时,将使用以下 configuration:

application.yml.

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000

115.5 PrefixPath GatewayFilter Factory

PrefixPath GatewayFilter Factory 采用单个prefix参数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://example.org
        filters:
        - PrefixPath=/mypath

这将/mypath前缀到所有匹配请求的路径。因此,对/hello的请求将被发送到/mypath/hello

115.6 PreserveHostHeader GatewayFilter Factory

PreserveHostHeader GatewayFilter Factory 没有参数。此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始 host 标头,而不是 http client 确定的 host 标头。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: http://example.org
        filters:
        - PreserveHostHeader

115.7 RequestRateLimiter GatewayFilter Factory

RequestRateLimiter GatewayFilter Factory 使用RateLimiter implementation 来确定是否允许当前请求继续。如果不是,则返回HTTP 429 - Too Many Requests(默认情况下)的状态。

此过滤器采用可选的keyResolver参数和特定于速率限制器的参数(参见下文)。

keyResolver是实现KeyResolver接口的 bean。在 configuration 中,使用 SpEL 通过 name 引用 bean。 #{@myKeyResolver}是一个引用带有 name myKeyResolver的 bean 的 SpEL 表达式。

KeyResolver.java.

public interface KeyResolver {
	Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver接口允许可插拔策略派生 key 以限制请求。在未来的里程碑中,会有一些KeyResolver __mplement。

KeyResolver的默认_imple 是PrincipalNameKeyResolver,它从ServerWebExchange和 calls Principal.getName()中检索Principal

RequestRateLimiter 不能通过“快捷方式”表示法进行配置。以下示例无效

application.properties.

# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

115.7.1 Redis RateLimiter

redis implementation 基于条纹完成的工作。它需要使用spring-boot-starter-data-redis-reactive Spring Boot starter。

使用的算法是令牌桶算法

redis-rate-limiter.replenishRate是您希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶填充的速率。

redis-rate-limiter.burstCapacity是用户在一秒钟内允许执行的最大请求数。这是令牌桶可以容纳的令牌数。将此 value 设置为零将阻止所有请求。

通过在replenishRateburstCapacity中设置相同的 value 来实现稳定的速率。通过将burstCapacity设置为高于replenishRate,可以允许临时突发。在这种情况下,需要在突发之间允许速率限制器一些 time(根据replenishRate),因为 2 个连续突发将导致请求被丢弃(HTTP 429 - Too Many Requests)。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://example.org
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20

Config.java.

@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

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

速率限制器也可以定义为实现RateLimiter接口的 bean。在 configuration 中,使用 SpEL 通过 name 引用 bean。 #{@myRateLimiter}是一个引用带有 name myRateLimiter的 bean 的 SpEL 表达式。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://example.org
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@myRateLimiter}"
            key-resolver: "#{@userKeyResolver}"

115.8 RedirectTo GatewayFilter Factory

RedirectTo GatewayFilter Factory 采用statusurl参数。状态应该是 300 系列重定向 http code,例如 301. url 应该是有效的 URL。这将是Location标题的 value。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://example.org
        filters:
        - RedirectTo=302, http://acme.org

这将发送带有Location:http://acme.org标头的状态 302 以执行重定向。

115.9 RemoveNonProxyHeaders GatewayFilter Factory

RemoveNonProxyHeaders GatewayFilter Factory 从转发的请求中删除 headers。删除的_header 的默认列表来自IETF

默认删除的 headers 是:

  • 连接

  • Keep-Alive

  • Proxy-Authenticate

  • Proxy-Authorization

  • TE

  • 预告片

  • Transfer-Encoding

  • 升级

要更改此设置,请将spring.cloud.gateway.filter.remove-non-proxy-headers.headers property 设置为要删除的标题名称列表。

115.10 RemoveRequestHeader GatewayFilter Factory

RemoveRequestHeader GatewayFilter Factory 采用name参数。它是要删除的标头的 name。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: http://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo

这将在向下游发送之前删除X-Request-Foo标头。

115.11 RemoveResponseHeader GatewayFilter Factory

RemoveResponseHeader GatewayFilter Factory 采用name参数。它是要删除的标头的 name。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: http://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo

这将在响应返回到网关 client 之前从响应中删除X-Response-Foo标头。

115.12 RewritePath GatewayFilter Factory

RewritePath GatewayFilter Factory 采用路径regexp参数和replacement参数。这使用 Java 正则表达式以灵活的方式来编写请求路径。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: http://example.org
        predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo/(?<segment>.*), /$\{segment}

对于/foo/bar的请求路径,这将在发出下游请求之前将路径设置为/bar。请注意$\由于 YAML 规范而被$替换。

115.13 SaveSession GatewayFilter Factory

SaveSession GatewayFilter Factory 在转发下游呼叫之前强制执行WebSession::save操作。当使用Spring Session这样的东西与惰性数据 store 时,这是特别有用的,并且需要确保在转发调用之前已保存 session state。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: http://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

如果要将Spring Security与 Spring Session 集成,并希望确保安全性详细信息已转发到 remote process,则这很关键。

115.14 SecureHeaders GatewayFilter Factory

SecureHeaders GatewayFilter Factory 在这篇博文的 reccomendation 中为响应添加了许多 headers。

添加以下_header(默认值为 allong):

  • 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命名空间中设置相应的 property:

要更改的财产:

  • xss-protection-header

  • strict-transport-security

  • frame-options

  • content-type-options

  • referrer-policy

  • content-security-policy

  • download-options

  • permitted-cross-domain-policies

115.15 SetPath GatewayFilter Factory

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

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: http://example.org
        predicates:
        - Path=/foo/{segment}
        filters:
        - SetPath=/{segment}

对于/foo/bar的请求路径,这将在发出下游请求之前将路径设置为/bar

115.16 SetResponseHeader GatewayFilter Factory

SetResponseHeader GatewayFilter Factory 采用namevalue参数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: http://example.org
        filters:
        - SetResponseHeader=X-Response-Foo, Bar

此 GatewayFilter 用给定的 name 替换所有_header,而不是添加。因此,如果下游服务器以X-Response-Foo:1234响应,则将替换为X-Response-Foo:Bar,这是网关客户端将接收的内容。

115.17 SetStatus GatewayFilter Factory

SetStatus GatewayFilter Factory 采用单个status参数。它必须是有效的 Spring HttpStatus。它可能是 integer value 404或枚举NOT_FOUND的 string 表示。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: http://example.org
        filters:
        - SetStatus=BAD_REQUEST
      - id: setstatusint_route
        uri: http://example.org
        filters:
        - SetStatus=401

在任何一种情况下,响应的 HTTP 状态都将设置为 401。

115.18 StripPrefix GatewayFilter Factory

StripPrefix GatewayFilter Factory 需要一个参数partsparts参数指示在向下游发送之前从请求中剥离的路径中的部分数。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: http://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

当通过网关向/name/bar/foo发出请求时,对nameservice的请求将看起来像http://nameservice/foo

115.19 重试 GatewayFilter Factory

Retry GatewayFilter Factory 将retriesstatusesmethodsseries作为参数。

  • retries:应尝试的重试次数

  • statuses:应重试的 HTTP 状态代码,使用org.springframework.http.HttpStatus表示

  • methods:应该重试的 HTTP 方法,使用org.springframework.http.HttpMethod表示

  • series:要重试的一系列状态代码,使用org.springframework.http.HttpStatus.Series表示

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

当使用带有forward:前缀 URL 的重试过滤器时,应仔细编写目标端点,以便在出现错误时不会执行任何可能导致响应发送到 client 并提交的操作。例如,如果目标端点是带注释的控制器,则目标控制器方法不应相反,它应该抛出Exception,或发出错误信号 e.g. 通过Mono.error(ex) return value,可以将重试过滤器配置为通过重试来处理。