五、Spring Cloud Gateway-路由过滤器工厂

路由过滤器允许用某种方式修改HTTP请求或响应。路由过滤器作用于一些特殊的路由。Spring Cloud Gateway包含了许多构建GatewayFilter的工厂。

注意:有关如何使用以下任何过滤器的更详细示例,请查看 unit tests

AddRequestHeader GatewayFilter Factory

AddRequestHeader GatewayFilter Factory 包括名称和值参数。

将所有匹配的请求,添加X-Request-Foo:Bar头信息。

AddRequestParameter GatewayFilter Factory

AddRequestParameter GatewayFilter Factory 包括名称和值参数。


将所有匹配的请求,添加 foo=bar参数信息。

AddResponseHeader GatewayFilter Factory

AddResponseHeader GatewayFilter Factory 包括名称和值参数。

将所有匹配的请求,返回头信息中添加X-Response-Foo:Bar信息。

DedupeResponseHeader GatewayFilter Factory

DedupeResponseHeader GatewayFilter Factory 采用名称参数和可选策略参数。名称可以包含头名称列表,以空格分隔。

这将删除访问Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin响应头的重复值,以防网关CORS逻辑和下游添加它们。

DedupeResponseHeader过滤器也可接收可选策略参数,可接收参数值包括:RETAIN_FIRST (default), RETAIN_LAST, and RETAIN_UNIQUE。

说明:

        1.该过滤器两个参数。第一个是去重敏感头信息,多个头信息之间以空格间隔;第二个是保留策略,默认是保留第一个。多个参数之间用逗号隔开;

          2.释义:参考上例。如果Access-Control-Allow-Credentials头中包含有多个值,那么通过可选策略进行保留。RETAIN_FIRST 保留第一个值(默认),RETAIN_LAST保留最后一个值,RETAIN_UNIQUE全部保留。Access-Control-Allow-Origin也是一样的。

Hystrix GatewayFilter Factory

Hystrix是一个来自Netflix的库,且实现了断路器模式( circuit breaker pattern)。 

Hystrix GatewayFilter允许您向网关路由引入断路器,保护您的服务不受级联故障的影响,并允许您在下游故障时提供回退响应。

Hystrix GatewayFilters引入,需要添加依赖spring-cloud-starter-netflix-hystrix来源于 Spring Cloud Netflix

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

其余的过滤器被包装在名称为myCommandName的HystrixCommand中。

Hystrix 过滤器也可接收一个可选的fallbackUri参数。目前,只支持forward: 预设URI。如果fallback被触发,请求将转发到URI匹配的控制层。

以上示例,当Hystrix fallback被触发时,该访问将被转发到/incaseoffailureusethis地址。注意这个例子也演示了Spring Cloud Netflix Ribbon负载均衡,通过lb前缀指向目标URI,当然这是可选的。

这里主要场景是使用fallbackUri指向一个在网关应用内部的controller或handler。也可能重新路由请求到controller或handler指向外部应用,例如:

在这个示例中,在网关应用中并没有fallback的endpoint 或handler,然而,他却在另一个应用中,注册在http://localhost:9994上。

如果请求被转发到fallback,Hystrix Gateway过滤器也提供了Throwable。它被添加在ServerWebExchange中,作为ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR的属性,在网关应用中执行fallback的时候可以使用。

如果是外部的controller/handler 应用场景,头能被添加异常详情。你可以找到更多信息在这里FallbackHeaders GatewayFilter Factory section

Hystrix设置(如超时)可以使用全局默认值进行配置,也可以使用Hystrix wiki中介绍的应用程序属性按路由进行配置。

设置5秒超时,触发熔断,你可以用如下方式设置:

FallbackHeaders GatewayFilter Factory

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

在此示例中,在运行HystrixCommand时发生执行异常后,请求将转发到localhost:9994上运行的应用程序中的fallback endpoint或handler。 具有异常类型,消息和-if available- root的头会导致异常类型和消息由FallbackHeaders过滤器添加到该请求中。

通过设置下面列出的参数的值及其默认值,可以在配置中覆盖头的名称:

executionExceptionTypeHeaderName ("Execution-Exception-Type")

executionExceptionMessageHeaderName ("Execution-Exception-Message")

rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")

rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")

您可以在中找到有关Hystrix如何与Gateway配合使用的更多信息 Hystrix GatewayFilter Factory section

PrefixPath GatewayFilter Factory

PrefixPath GatewayFilter Factory 只有一个前缀参数。

/mypath前缀将匹配所有的请求,例如请求  /hello,将发送到后台为 /mypath/hello。

备注:如果设置了多个,第一个生效。

PreserveHostHeader GatewayFilter Factory

PreserveHostHeader GatewayFilter Factory无参数。设置此属性后,发送原始Host头,而不是http客户端确定的Host头。

备注:当客服端通过Gateway访问服务时,服务中获取到Host头。如果经过此过滤器,则服务端获取到的是客户端请求网关的Host;如果未经过此过滤器,则服务端获取到的是网关请求服务端的Host。

RequestRateLimiter GatewayFilter Factory

RequestRateLimiter GatewayFilter Factory 使用RateLimiter实现来确定是否允许继续执行当前请求。如果不通过,返回HTTP状态值429。太多请求时(默认)被返回。

这个过滤器接受一个可选的keysolver参数和特定于速率限制器的参数(见下文)。

keyResolver 是个实现了KeyResolver接口的bean。 在配置中,bean使用SpEL表达式:#{@myKeyResolver} ,其中myKeyResolver为bean的名称。

KeyResolver 接口允许插件策略派生key来做请求限流。在未来,将实现一些KeyResolver。

KeyResolver的默认实现是PrincipalNameKeyResolver,它从ServerWebExchange检索主体并调用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不可以通过 "shortcut" 符号配置,以下为错误示例:

Redis RateLimiter

redis实现基于Stripe完成的工作。 它需要使用spring-boot-starter-data-redis -active Spring Boot starter。

算法使用的是令牌桶算法 Token Bucket Algorithm.

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

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

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


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

限速器也可以定义为实现RateLimiter接口的bean。 在配置中,使用SpEL按名称引用bean。 #{@ myRateLimiter}是一个引用名为myRateLimiter的bean的SpEL表达式。

RedirectTo GatewayFilter Factory

RedirectTo GatewayFilter Factory 包含状态参数和地址参数。 状态参数必须是300系列的重定向http状态码,例如301。地址必须有效,这将是Location头的值。

这将发送状态302和Location:https://acme.org头以执行重定向。

说明:服务端返回302后,重定向到https://acme.org地址。

RemoveHopByHopHeadersFilter GatewayFilter Factory

RemoveHopByHopHeadersFilter GatewayFilter Factory从转发的请求中删除头。 删除的头列表来自IETF

默认删除的头包括:

Connection

Keep-Alive

Proxy-Authenticate

Proxy-Authorization

TE

Trailer

Transfer-Encoding

Upgrade

要更改此设置,请将spring.cloud.gateway.filter.remove-non-proxy-headers.headers属性设置为要删除的头名称列表(其作用于request及response)。

RemoveRequestHeader GatewayFilter Factory

RemoveRequestHeader GatewayFilter Factory 包含一个name参数。该name头属性将被移除。

X-Request-Foo名称的头信息在被下游接收前被移除。

说明:移除多个头信息时按照如果方式写,删除请求头中test1、test2。

RemoveResponseHeader GatewayFilter Factory

RemoveResponseHeader GatewayFilter Factory包含一个name参数。该name头属性将被删除。

X-Response-Foo名称的头信息在下游返回对象中移除,最终网关客户端不能看到。

要删除任何类型的敏感头,你应该配置这些过滤器在你想加的路由中,也可以使用spring.cloud.gateway.default-filters配置此过滤器,并将其应用于所有路由。

说明:移除多个头信息时按照如果方式写,删除响应头中test1、test2。

RewritePath GatewayFilter Factory

RewritePath GatewayFilter Factory包括路径(正则表达式)参数和替换参数。这使用Java正则表达式来灵活地重写请求路径。

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

说明:1.重写路径共两个参数,regexp和replacement,其中regexp可以是正则表达式。将请求路径中包含regexp的内容,全部替换为replacement;

          2.在上例中,如果"$"后面不带"\",yaml文件中就会识别为获取segment变量;

          3.可以写多个RewritePath 过滤器,通常是按照顺序执行。第二次替换的请求路径是基于第一次加工的结果。

RewriteResponseHeader GatewayFilter Factory

RewriteResponseHeader GatewayFilter Factory包括名称,正则表达式和替换参数。这使用Java正则表达式来灵活地重写返回头值。

对于头信息中值为 /42?user=ford&password=omg!what&flag=true, 将被设置为 /42?user=ford&password=***&flag=true .。注意由于YAML规范,$\替换为$。

备注:上例中是三个参数,第一个是头信息中的参数名称;第二个是正则表达式,第三个是字符串。通过第一个参数获取头信息值,将值中匹配第二个参数的内容,替换成第三个参数。

SaveSession GatewayFilter Factory

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

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

说明:session存在内存中,那如果多个节点的时候,该如何处理?

          1.可以通过网关前端的hash路由等策略来实现,用户被分配到固定的机器上;

         2.对于多节点session同步,可以通过第三方存储来实现,例如redis等。

SecureHeaders GatewayFilter Factory

SecureHeaders GatewayFilter Factory在响应时添加一些在此博文中推荐的头信息。

添加以下标头(以及默认值):

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

frame-options

content-type-options

referrer-policy

content-security-policy

download-options

permitted-cross-domain-policies

要禁用默认值,请使用逗号分隔值设置属性spring.cloud.gateway.filter.secure-headers.disable。

例如:

spring.cloud.gateway.filter.secure-headers.disable=frame-options,download-options

说明:此过滤器是安全增强过滤器,可以为用户方便提供一些安全属性。当然,也可以通过配置属性,去掉其中一部分安全属性。

SetPath GatewayFilter Factory

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

以上示例,请求 /foo/bar,在向下游请求前,此路径修改为/bar。

备注:SetPath 与RewritePath 都用来修改请求路径的过滤器,但它们使用不同方式:

           1. SetPath 设置路径,将原有路径覆盖;或者通过变量模板的方式,截取部分路径;

           2. RewritePath  将访问路径中,符合正则表达式内容,替换为目标内容。

SetResponseHeader GatewayFilter Factory

SetResponseHeader GatewayFilter Factory 包含名称和值参数。

此GatewayFilter用给定名称替换所有标头,而不是添加。因此,如果下游服务器使用X-Response-Foo:1234进行响应,则会将其替换为X-Response-Foo:Bar,这是网关客户端将收到的内容。

SetStatus GatewayFilter Factory

SetStatus GatewayFilter Factory采用单个状态参数。 它必须是有效的Spring HttpStatus。 它可以是整数值404或枚举NOT_FOUND的字符串表示形式。

在以上情况,响应的HTTP状态都将设置为400(BAD_RQUEST)或者401。

备注:如果过滤器中配置了多个SetStatus,默认返回第一个状态码。

StripPrefix GatewayFilter Factory

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

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

Retry GatewayFilter Factory

Retry GatewayFilter Factory包括 retries, statuses, methods, 和series作为参数。

retries: 尝试的重发次数;

statuses: 要重试的HTTP状态码,使用org.springframework.http.HttpStatus表示;

methods: 要重试的HTTP请求方法, 使用org.springframework.http.HttpMethod表示;

series: 要重试的一系列状态码(理解该状态对应HTTP多个状态码),使用org.springframework.http.HttpStatus.Series表示。

重试过滤器当前不支持使用body请求的重试(例如,对于具有body的POST或PUT请求)。

当使用带有forward: prefixed URL的重试过滤器时,应仔细编写目标端点,以便在出现错误时不会执行任何可能导致响应发送到客户端并提交的操作。例如:如果目标端是一个注解控制器,该控制器的方法不应该返回带有错误状态码的ResponseEntity对象,应该抛出异常或者发出错误信号,例如通过 Mono.error(ex) 返回值。这样重试过滤器才进行重试。

说明:series、statuses、methods参数可以是多个,且以逗号隔开。

RequestSize GatewayFilter Factory

当请求大小大于允许的限制时,RequestSize GatewayFilter Factory可以限制请求到达下游服务。过滤器将RequestSize作为参数,该参数是以字节为单位定义的请求的允许大小限制。

RequestSize GatewayFilter Factory将响应状态设置为413,当负载太大时,并在请求因大小而被拒绝时添加标头errorMessage。示例说明:

     errorMessage : 请求大小大于允许的限制。 请求大小为6 MB,允许的限制为5 MB。

如果未在路由定义中提供过滤器参数,则默认请求大小将设置为5 MB。

Modify Request Body GatewayFilter Factory

此过滤器被视为BETA,API可能在将来发生变化

此过滤器可以修改请求body内容,通过网关被发送到下游前进行。

此过滤只能使用Java DSL进行配置,不支持YAML配置。 

Modify Response Body GatewayFilter Factory

此过滤器被视为BETA,API可能在将来发生变化

此过滤器被用在修改返回body内容,在发送给客户前。

此过滤只能使用Java DSL进行配置,不支持YAML配置。

Default Filters

如果您想添加过滤器并将其应用于所有路由,可以使用spring.cloud.gateway.default-filters。 此属性采用过滤器列表。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容