【Spring Gateway】 局部过滤器

Metadata

title: 【Spring Gateway】 局部过滤器
date: 2023-02-14 09:05
tags:
  - 行动阶段/完成
  - 主题场景/组件
  - 笔记空间/KnowladgeSpace/ProgramSpace/ModuleSpace
  - 细化主题/Module/SpringGateway
categories:
  - SpringGateway
keywords:
  - SpringGateway
description: 【Spring Gateway】 局部过滤器

【Spring Gateway】 局部过滤器

AddRequestHeader

AddRequestHeader GatewayFilter工厂接受一个名称和值参数。配置AddRequestHeader网关过滤器的示例如下:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue

该清单将X-Request-red:blue报头添加到所有匹配请求的下游请求报头中。

AddRequestHeader知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个使用变量的AddRequestHeader GatewayFilter:

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

AddRequestParameter

AddRequestParameter GatewayFilter Factory接受一个名称和值参数。配置AddRequestParameter GatewayFilter的示例如下:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=red, blue

这将为所有匹配的请求将red=blue添加到下游请求的查询字符串中。
AddRequestParameter知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个AddRequestParameter GatewayFilter,它使用了一个变量:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddRequestParameter=foo, bar-{segment}

AddResponseHeader

AddResponseHeader GatewayFilter Factory接受一个名称和值参数。配置AddResponseHeader GatewayFilter的示例如下:

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Blue

这将把X-Response-Red:Blue报头添加到所有匹配请求的下游响应报头中。

AddResponseHeader知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的示例配置了一个使用变量的AddResponseHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}

DedupeResponseHeader

DedupeResponseHeader GatewayFilter工厂接受一个名称参数和一个可选的策略参数。名称可以包含以空格分隔的标题名称列表。配置DedupeResponseHeader GatewayFilter的示例如下:

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。

CircuitBreaker

Spring Cloud circuit breaker网关过滤器工厂使用Spring Cloud circuit breaker api将网关路由封装在一个断路器中。Spring Cloud CircuitBreaker支持多个可以与Spring Cloud Gateway一起使用的库。Spring Cloud开箱即用地支持Resilience4J。

要启用Spring Cloud CircuitBreaker过滤器,您需要在类路径上放置Spring-Cloud-starter-CircuitBreaker-reactor-resili4j。配置Spring Cloud CircuitBreaker GatewayFilter的示例如下:

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

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

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

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();
}

当断路器回退被调用时,这个例子转发到/inCaseofFailureUseThis URI。注意,这个示例还演示了(可选的)Spring Cloud LoadBalancer负载均衡(由目标URI上的lb前缀定义)。

主要场景是使用fallbackUri在网关应用程序中定义内部控制器或处理程序。但是,你也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:

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下注册。

如果请求被转发到回退,Spring Cloud CircuitBreaker Gateway过滤器还提供了引起它的Throwable。作为添加到ServerWebExchange。ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR属性,可以在网关应用程序中处理回退时使用。

对于外部控制器/处理器场景,可以添加带有异常详细信息的标头。您可以在FallbackHeaders GatewayFilter Factory一节中找到更多关于这样做的信息。

FallbackHeaders

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

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

在本例中,在运行断路器时发生执行异常后,请求被转发到运行在localhost:9994上的应用程序中的回退端点或处理程序。FallbackHeaders过滤器将带有异常类型、消息以及(如果可用)根原因异常类型和消息的报头添加到该请求中。

您可以通过设置以下参数的值(显示其默认值)来覆盖配置中的头的名称:

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

MapRequestHeader

MapRequestHeader GatewayFilter工厂接受fromHeader和toHeader参数。它创建了一个新的命名头(toHeader),该值从传入的http请求中已存在的命名头(fromHeader)中提取出来。如果输入头不存在,筛选器就没有影响。如果新的命名头已经存在,则它的值将使用新值进行扩充。配置MapRequestHeader的示例如下:

spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        - MapRequestHeader=Blue, X-Request-Red

这将X-Request-Red:<values>报头添加到下游请求,并使用来自传入HTTP请求的蓝色报头的更新值。

PrefixPath

PrefixPath GatewayFilter工厂接受一个前缀参数。使用实例配置PrefixPath GatewayFilter:

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

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

PreserveHostHeader

PreserveHostHeader GatewayFilter工厂没有参数。这个筛选器设置一个请求属性,路由筛选器检查该属性以确定是否应该发送原始的主机报头,而不是HTTP客户端确定的主机报头。配置一个PreserveHostHeader网关过滤器的示例如下:

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

RequestRateLimiter

RequestRateLimiter GatewayFilter工厂使用一个RateLimiter实现来确定当前请求是否被允许继续。如果不是,返回HTTP 429 - Too Many Requests(默认)的状态。

该过滤器接受一个可选的keyResolver参数和特定于速率限制器的参数(本节稍后将介绍)。

keyResolver是一个实现keyResolver接口的bean。在配置中,使用SpEL按名称引用bean。#{@myKeyResolver}是一个引用名为myKeyResolver的bean的SpEL表达式。下面的清单显示了KeyResolver接口:

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

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

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

默认情况下,如果KeyResolver没有找到密钥,请求将被拒绝。你可以通过设置spring.cloud.gateway.filter.request-rate- limititer.deny-empty-key (true或false)和spring.cloud.gateway.filter.request-rate- limititer来调整这种行为。empty-key-status-code属性。

The Redis RateLimiter

Redis的实现基于Stripe所做的工作。它需要使用Spring - Boot -starter-data-redis-reactive Spring Boot启动程序。

redis-rate-limiter。属性是指在不丢弃任何请求的情况下,允许用户每秒执行多少个请求。这是令牌桶被填充的速率。

redis-rate-limiter。burstCapacity属性是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以容纳的令牌数量。将该值设置为0将阻塞所有请求。

redis-rate-limiter。requestedTokens属性表示请求花费了多少令牌。这是为每个请求从桶中取出的令牌数量,默认为1。

一个稳定的速率是通过在“补速率”和“爆裂容量”中设置相同的值来实现的。可以通过将burstCapacity设置为高于replenishRate来允许临时爆发。在这种情况下,需要允许速率限制器在爆发之间有一定的时间(根据replenishRate),因为连续两次爆发将导致请求丢失(HTTP 429 -太多请求)。下面的清单配置了一个redis-rate- limititer:

1请求/秒以下的速率限制是通过将replenishRate设置为所需的请求数量,将requestedTokens设置为以秒为单位的时间间隔,将burstCapacity设置为replenishRate和requestedTokens的乘积来实现的,例如设置replenishRate=1, requestedTokens=60和burstCapacity=60将导致1个请求/分钟的限制。

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的示例如下:

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

RedirectTo

RedirectTo GatewayFilter工厂接受两个参数: status和url。status参数应该是一个300系列重定向HTTP代码,例如301。url参数应该是一个有效的url。这是Location报头的值。对于相对重定向,你应该使用uri: no://op作为路由定义的uri。下面的清单配置了一个RedirectTo GatewayFilter:

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

这将发送带有Location:https://acme.org报头的状态302来执行重定向。

RemoveRequestHeader

RemoveRequestHeader GatewayFilter工厂接受一个name参数。它是要删除的标头的名称。下面的清单配置了一个RemoveRequestHeader GatewayFilter:

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

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

RemoveResponseHeader

RemoveResponseHeader GatewayFilter工厂接受一个name参数。它是要删除的标头的名称。下面的清单配置了一个RemoveResponseHeader GatewayFilter:

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

这将在响应返回到网关客户端之前从响应中删除X-Response-Foo报头。

要删除任何类型的敏感报头,您应该为任何您想要这样做的路由配置此过滤器。此外,您可以使用spring.cloud.gateway.default-filters配置此过滤器一次,并将其应用于所有路由。

RemoveRequestParameter

RemoveRequestParameter GatewayFilter工厂接受一个name参数。它是要删除的查询参数的名称。使用实例配置RemoveRequestParameter GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red

这将在发送到下游之前删除红色参数。

RequestHeaderSize

RequestHeaderSize GatewayFilter工厂接受maxSize和errorHeaderName参数。maxSize参数是请求头允许的最大数据大小(包括键和值)。参数errorHeaderName设置包含错误消息的响应头的名称,默认为”errorMessage”。下面的清单配置了一个RequestHeaderSize GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: requestheadersize_route
        uri: https://example.org
        filters:
        - RequestHeaderSize=1000B

如果任何请求头的大小大于1000字节,这将发送一个状态431。

RewritePath

RewritePath GatewayFilter工厂接受一个路径regexp参数和一个替换参数。它使用Java正则表达式作为一种灵活的方式来重写请求路径。下面的清单配置了一个RewritePath GatewayFilter:

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

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

RewriteLocationResponseHeader

RewriteLocationResponseHeader GatewayFilter工厂修改Location响应头的值,通常是为了去掉后端特定的细节。它接受stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数。下面的清单配置了一个RewriteLocationResponseHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: rewritelocationresponseheader_route
        uri: http://example.org
        filters:
        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

例如,对于POST api.example.com/some/object/name的请求,object-service.prod.example.net/v2/some/object/id的Location响应头值被重写为api.example.com/some/object/id

stripVersionMode参数取值包括:NEVER_STRIP、AS_IN_REQUEST(默认值)和ALWAYS_STRIP。

  • NEVER_STRIP:不剥离版本,即使原始请求路径不包含版本。
  • AS_IN_REQUEST只有在原始请求路径不包含版本时才会剥离版本。
  • ALWAYS_STRIP版本总是被剥离,即使原始请求路径包含version。

如果提供了hostValue参数,则用于替换响应Location报头的host:port部分。如果没有提供,则使用Host请求头的值。

参数protocolsRegex必须是一个有效的正则表达式字符串,协议名要匹配该正则表达式字符串。如果不匹配,筛选器什么也不做。缺省为http|https|ftp|ftps。

RewriteResponseHeader

RewriteResponseHeader GatewayFilter工厂接受名称、regexp和替换参数。它使用Java正则表达式来灵活地重写响应头值。下面的例子配置一个RewriteResponseHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: rewriteresponseheader_route
        uri: https://example.org
        filters:
        - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***

对于头值为/42?user=ford&password=omg!what&flag=true,它被设置为/42?发出下游请求后user=ford&password=***&flag=true由于YAML规范,您必须使用$\表示$

SaveSession

SaveSession GatewayFilter工厂在向下游转发调用之前强制执行WebSession::save操作。这在使用带有惰性数据存储的Spring Session之类的东西时特别有用,并且您需要确保在进行前转调用之前已经保存了会话状态。配置一个SaveSession GatewayFilter的示例如下:

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

如果您将Spring Security与Spring Session集成在一起,并希望确保安全细节已被转发到远程进程,这是至关重要的。

SecureHeaders

SecureHeaders GatewayFilter工厂根据本文的建议向响应中添加了许多报头。

添加以下头部(显示其默认值):

  • X-Xss-Protection:1 (mode=block)
  • Strict-Transport-Security (max-age=631138519)
  • X-Frame-Options (DENY)
  • X-Content-Type-Options (nosniff)
  • Referrer-Policy (no-referrer)
  • Content-Security-Policy (default-src ‘self’ https:; font-src ‘self’ https: data:; img-src ‘self’ https: data:; object-src ‘none’; script-src https:; style-src ‘self’ https: ‘unsafe-inline)’
  • X-Download-Options (noopen)
  • X-Permitted-Cross-Domain-Policies (none)

要更改默认值,请在spring.cloud.gateway.filter中设置适当的属性。secure-headers名称空间。可以使用以下属性:

  • xss-protection-header
  • strict-transport-security
  • x-frame-options
  • x-content-type-options
  • referrer-policy
  • content-security-policy
  • x-download-options
  • x-permitted-cross-domain-policies

要禁用默认值,请设置spring.cloud.gateway.filter.secure-headers。禁用值以逗号分隔的属性。下面的例子展示了如何这样做:

spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security

SetPath

SetPath GatewayFilter工厂接受一个路径模板参数。它通过允许路径的模板段提供了一种操作请求路径的简单方法。这使用了Spring Framework中的URI模板。允许有多个匹配段。配置SetPath GatewayFilter的示例如下:

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

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

SetRequestHeader

SetRequestHeader GatewayFilter工厂接受名称和值参数。下面的清单配置了一个SetRequestHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        filters:
        - SetRequestHeader=X-Request-Red, Blue

这个GatewayFilter用给定的名称替换(而不是添加)所有头部。因此,如果下游服务器响应X-Request-Red:1234,则该响应将被替换为X-Request-Red:Blue,这就是下游服务将接收到的内容。

SetRequestHeader知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个使用变量的SetRequestHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetRequestHeader=foo, bar-{segment}

SetResponseHeader

SetResponseHeader GatewayFilter工厂接受名称和值参数。下面的清单配置了一个SetResponseHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        filters:
        - SetResponseHeader=X-Response-Red, Blue

这个GatewayFilter用给定的名称替换(而不是添加)所有头部。因此,如果下游服务器响应X-Response-Red:1234,则将其替换为X-Response-Red:Blue,这就是网关客户端将收到的内容。

SetResponseHeader知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并将在运行时展开。下面的例子配置了一个使用变量的SetResponseHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetResponseHeader=foo, bar-{segment}

SetStatus

SetStatus GatewayFilter工厂接受一个参数status。它必须是一个有效的Spring HttpStatus。它可以是整型值404或枚举的字符串表示形式:NOT_FOUND。下面的清单配置了一个SetStatus GatewayFilter:

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

在这两种情况下,响应的HTTP状态都设置为401。

您可以配置SetStatus GatewayFilter,以在响应的报头中返回代理请求的原始HTTP状态代码。如果配置了以下属性,报头将被添加到响应中:

spring:
  cloud:
    gateway:
      set-status:
        original-status-header-name: original-http-status

StripPrefix

StripPrefix GatewayFilter工厂接受一个参数parts。parts参数表示在将请求发送到下游之前要从请求中剥离的路径中的部件数量。下面的清单配置了一个StripPrefix GatewayFilter:

StripPrefix 在我们当前请求中,通过规则值去掉某一部分地址,比如我们有一台服务中加入了一个前端nacos-provider想要通过这个去访问,我们在项目cloud-alibaba-nacos-9001中加入 context-path

server:
  port: 9001
  servlet:
    context-path: /nacos-provider

现在9001的访问路径变为http://localhost:9001/nacos-provider/mxn/hello,但是如果我们通过网关去访问路径就会变成http://localhost:9006/mxn/nacos-provider/mxn/hello 这个时候我们通过这个路径去访问是访问不成功的,想要解决这个方法,这个就用到了我们FIlter 中的 StripPrefix

routes:  # 路由
  - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
    uri: lb://nacos-provider
    predicates: # 断言
      - Path=/mxn/** # 匹配对应地址
    filters:
      - StripPrefix=1 # 去掉地址中的第一部分

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

当通过网关向/name/blue/red发出请求时,向nameservice发出的请求看起来像nameservice/red。

Retry

Retry GatewayFilter工厂支持以下参数:

  • retries:应该尝试的重试次数。
  • status:应该重试的HTTP状态代码,用org.springframework.http.HttpStatus表示。
  • methods:应该重试的HTTP方法,用org.springframework.http.HttpMethod表示。
  • series:要重试的状态代码系列,由org.springframework.http.HttpStatus.Series表示。
  • exceptions:抛出的应该重试的异常列表。
  • backoff:配置的重试次数的指数级回退。在firstBackoff * (factor ^ n)的回退间隔后执行重试,其中n是迭代。如果配置了maxBackoff,则应用的最大回退限制为maxBackoff。如果basedOnPreviousValue为true,则使用prevBackoff * factor计算回退。

如果启用重试筛选器,则配置以下默认值:

  • retries: Three times
  • series: 5XX series
  • methods: GET method
  • exceptions: IOException and TimeoutException
  • backoff: disabled
spring:
  cloud:
    gateway:
      routes:
      - id: retry_test
        uri: http://localhost:8080/flakey
        predicates:
        - Host=*.retry.com
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY
            methods: GET,POST
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false

可以使用单一的状态和方法添加简化的“快捷”符号。

下面两个例子是等价的:

spring:
  cloud:
    gateway:
      routes:
      - id: retry_route
        uri: https://example.org
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: INTERNAL_SERVER_ERROR
            methods: GET
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false

      - id: retryshortcut_route
        uri: https://example.org
        filters:
        - Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false

RequestSize

当请求大小大于允许的限制时,RequestSize GatewayFilter工厂可以限制请求到达下游服务。过滤器接受一个maxSize参数。maxSize是一个DataSize类型,所以值可以定义为一个数字后面跟着一个可选的DataUnit后缀,如’KB’或’MB’。默认是’B’表示字节。它是以字节为单位定义的请求的允许大小限制。下面的清单配置了一个RequestSize GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

RequestSize GatewayFilter工厂将响应状态设置为413 Payload Too Large,当请求因大小而被拒绝时,会附加一个报头errorMessage。下面的例子显示了这样一个errorMessage:

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

SetRequestHostHeader

在某些情况下,主机头可能需要被覆盖。在这种情况下,SetRequestHostHeader GatewayFilter工厂可以用指定的值替换现有的主机头。筛选器接受一个主机参数。下面的清单配置了SetRequestHostHeader GatewayFilter:

spring:
  cloud:
    gateway:
      routes:
      - id: set_request_host_header_route
        uri: http://localhost:8080/headers
        predicates:
        - Path=/headers
        filters:
        - name: SetRequestHostHeader
          args:
            host: example.org

SetRequestHostHeader GatewayFilter工厂用example.org替换主机头的值。

ModifyRequestBody

您可以使用ModifyRequestBody筛选器筛选器在请求正文被网关发送到下游之前修改它。

下面的列表显示了如何修改请求体GatewayFilter:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
                    (exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
        .build();
}

static class Hello {
    String message;

    public Hello() { }

    public Hello(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

如果请求没有正文,RewriteFilter将被传递为null。应该返回Mono.empty()来分配请求中缺少的主体。

ModifyResponseBody

在将响应体发送回客户端之前,可以使用ModifyResponseBody筛选器修改响应体。

下面的清单显示了如何修改响应体GatewayFilter:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyResponseBody(String.class, String.class,
                    (exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
        .build();
}

TokenRelay

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

Spring Cloud Gateway可以将OAuth2访问令牌转发到它代理的下游服务。要把这个功能添加到gateway,你需要像这样添加TokenRelayGatewayFilterFactory:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("resource", r -> r.path("/resource")
                    .filters(f -> f.tokenRelay())
                    .uri("http://localhost:9000"))
            .build();
}

或者

spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

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

要为Spring Cloud Gateway启用此功能,请添加以下依赖项

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

TokenRelayGatewayFilterFactory bean只会在适当的spring.security.oauth2.client。*属性的设置将触发ReactiveClientRegistrationRepository bean的创建。


```ad-info
TokenRelayGatewayFilterFactory使用的ReactiveOAuth2AuthorizedClientService的默认实现使用内存中的数据存储。如果需要更健壮的解决方案,则需要提供自己的ReactiveOAuth2AuthorizedClientService实现。

CacheRequestBody

有一定的情况需要阅读身体。由于请求体流只能读取一次,所以我们需要缓存请求体。您可以使用CacheRequestBody过滤器在请求正文发送到下游之前缓存请求正文,并从exchangagne属性获取请求正文。

下面的列表显示了如何缓存请求体GatewayFilter:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("cache_request_body_route", r -> r.path("/downstream/**")
            .filters(f -> f.prefixPath("/httpbin")
                .cacheRequestBody(String.class).uri(uri))
        .build();
}
spring:
  cloud:
    gateway:
      routes:
      - id: cache_request_body_route
        uri: lb://downstream
        predicates:
        - Path=/downstream/**
        filters:
        - name: CacheRequestBody
          args:
            bodyClass: java.lang.String

CacheRequestBody将提取请求正文并将其转换为正文类(例如java.lang.body)。字符串,在前面的例子中定义)。然后将其放入ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR中定义的键serverwebexchangeutils.getattributes()中。

JsonToGrpc

JSONToGRPCFilter GatewayFilter Factory将JSON有效负载转换为gRPC请求。

过滤器接受以下参数:

  • protoDescriptor 原型描述符文件。

这个文件可以使用指定--descriptor_set_out标志的协议生成:

protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb  \
src/main/resources/proto/hello.proto
  • protoFile 原型定义文件。
  • service 将处理请求的服务的完全限定名称。
  • method 服务中处理请求的方法名。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("json-grpc", r -> r.path("/json/hello").filters(f -> {
                String protoDescriptor = "file:src/main/proto/hello.pb";
                String protoFile = "file:src/main/proto/hello.proto";
                String service = "HelloService";
                String method = "hello";
                return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
            }).uri(uri))
spring:
  cloud:
    gateway:
      routes:
        - id: json-grpc
          uri: https://localhost:6565/testhello
          predicates:
            - Path=/json/**
          filters:
            - name: JsonToGrpc
              args:
                protoDescriptor: file:proto/hello.pb
                protoFile: file:proto/hello.proto
                service: com.example.grpcserver.hello.HelloService
                method: hello

当一个请求通过网关发送到/json/hello时,请求将使用hello中提供的定义进行转换。Proto,发送到com.example.grpcserver.hello.HelloService/hello,并将响应转换回JSON。

默认情况下,它将使用默认的TrustManagerFactory创建一个NettyChannel。但是,这个TrustManager可以通过创建一个GrpcSslConfigurer类型的bean来定制:

@Configuration
public class GRPCLocalConfiguration {
    @Bean
    public GRPCSSLContext sslContext() {
        TrustManager trustManager = trustAllCerts();
        return new GRPCSSLContext(trustManager);
    }
}

Default

要添加一个过滤器并将其应用于所有路由,可以使用spring.cloud.gateway.default-filters。此属性接受一个筛选器列表。下面的清单定义了一组默认过滤器:

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin