余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Spring Cloud Gateway-过滤器工厂详解-GatewayFilter Factories

xiyangw 2023-10-08 13:55 16 浏览 0 评论

TIPS

本文基于 Spring Cloud Greenwich SR2 ,理论支持 Spring Cloud Greenwich SR1 ,其中的新特性标注出来了。

本文探讨Spring Cloud Gateway内置的Filter工厂。包括:

?AddRequestHeader GatewayFilter Factory

?AddRequestParameter GatewayFilter Factory

?AddResponseHeader GatewayFilter Factory

?DedupeResponseHeader GatewayFilter Factory

?Hystrix GatewayFilter Factory

?FallbackHeaders GatewayFilter Factory

?PrefixPath GatewayFilter Factory

?PreserveHostHeader GatewayFilter Factory

?RequestRateLimiter GatewayFilter Factory

?RedirectTo GatewayFilter Factory

?RemoveHopByHopHeadersFilter GatewayFilter Factory

?RemoveRequestHeader GatewayFilter Factory

?RemoveResponseHeader GatewayFilter Factory

?RewritePath GatewayFilter Factory

?RewriteResponseHeader GatewayFilter Factory

?SaveSession GatewayFilter Factory

?SecureHeaders GatewayFilter Factory

?SetPath GatewayFilter Factory

?SetResponseHeader GatewayFilter Factory

?SetStatus GatewayFilter Factory

?StripPrefix GatewayFilter Factory

?Retry GatewayFilter Factory

?RequestSize GatewayFilter Factory

?Modify Request Body GatewayFilter Factory

?Modify Response Body GatewayFilter Factory

?Default Filters

技巧

1 断点打在 org.springframework.cloud.gateway.filter.NettyRoutingFilter#filter ,就可以调试Gateway转发的具体细节了。

2 添加如下配置,可观察到一些请求细节:

logging:
 level:
 org.springframework.cloud.gateway: trace
 org.springframework.http.server.reactive: debug
 org.springframework.web.reactive: debug
 reactor.ipc.netty: debug

1 AddRequestHeader GatewayFilter Factory

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

为原始请求添加名为 X-Request-Foo ,值为 Bar 的请求头。

2 AddRequestParameter GatewayFilter Factory

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

为原始请求添加请求参数 foo=bar

3 AddResponseHeader GatewayFilter Factory

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

添加名为 X-Request-Foo ,值为 Bar 的响应头。

4 DedupeResponseHeader GatewayFilter Factory

TIPS

Spring Cloud Greenwich SR2提供的新特性,低于这个版本无法使用。

强烈建议阅读一下类org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory上的注释,比官方文档写得还好。

spring:
 cloud:
 gateway:
 routes:
 - id: dedupe_response_header_route
 uri: https://example.org
 filters:
 - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST

剔除重复的响应头。

举个例子:

我们在Gateway以及微服务上都设置了CORS(解决跨域)header,如果不做任何配置,请求 -> 网关 -> 微服务,获得的响应就是这样的:

Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://musk.mars, https://musk.mars

也就是Header重复了。要想把这两个Header去重,只需设置成如下即可。

filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

也就是说,想要去重的Header如果有多个,用空格分隔即可;

去重策略:

RETAIN_FIRST: 默认值,保留第一个值
RETAIN_LAST: 保留最后一个值
RETAIN_UNIQUE: 保留所有唯一值,以它们第一次出现的顺序保留

5 Hystrix GatewayFilter Factory

TIPS

Hystrix是Spring Cloud第一代中的容错组件,不过已经进入维护模式(相关文章: Spring Cloud Netflix项目进入维护模式之我见[1]未来,Hystrix会被Spring Cloud移除掉,取而代之的是Alibaba Sentinel/Resilience4J

所以本文不做详细探讨了,但Gateway整合Hystrix其实包含了很多姿势。请感兴趣的同学自行前往官方文档了解详情:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#hystrix 。

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

6 FallbackHeaders GatewayFilter Factory

TIPS

也是对Hystrix的支持,不做详细探讨了,请感兴趣的同学自行前往官方文档了解详情:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#fallback-headers

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
 filters:
 - name: FallbackHeaders
 args:
 executionExceptionTypeHeaderName: Test-Header

7 PrefixPath GatewayFilter Factory

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

为匹配的路由添加前缀。例如:访问${GATEWAY_URL}/hello 会转发到https://example.org/mypath/hello 。

8 PreserveHostHeader GatewayFilter Factory

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

如果不设置,那么名为 Host 的Header由Http Client控制;如果设置了,那么会设置一个请求属性(preserveHostHeader=true),路由过滤器会检查从而去判断是否要发送原始的、名为Host的Header。

9 RequestRateLimiter GatewayFilter Factory

TIPS

在视频Spring Cloud Gateway一章,限流一节会详细讲解。也可阅读官方文档 https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#_requestratelimiter_gatewayfilter_factory

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

10 RedirectTo GatewayFilter Factory

spring:
 cloud:
 gateway:
 routes:
 - id: prefixpath_route
 uri: https://example.org
 filters:
 # 配置成HTTP状态码, URL的形式
 - RedirectTo=302, http://www.itmuch.com

?HTTP状态码应该是HTTP状态码300序列,例如301

?URL必须是合法的URL,并且该值会作为名为 Location 的Header。

上面配置表达的意思是: ${GATEWAY_URL}/hello 会重定向到 https://ecme.org/hello ,并且携带一个 Location:http://www.itmuch.com 的Header。

11 RemoveHopByHopHeadersFilter GatewayFilter Factory

spring.cloud.gateway.filter.remove-hop-by-hop.headers: Connection,Keep-Alive

移除转发请求的Header,多个用 , 分隔。默认情况下,移除如下Header。这些Header是由 IETF[2] 组织规定的。

?Connection

?Keep-Alive

?Proxy-Authenticate

?Proxy-Authorization

?TE

?Trailer

?Transfer-Encoding

?Upgrade

12 RemoveRequestHeader GatewayFilter Factory

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

为原始请求删除名为 X-Request-Foo 的请求头。

13 RemoveResponseHeader GatewayFilter Factory

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

删除名为 X-Request-Foo 的响应头。

14 RewritePath GatewayFilter Factoryspring:

cloud:

gateway:

routes:

- id: rewritepath_route

uri: https://example.org

predicates:

- Path=/foo/**

filters:

# 配置成原始路径正则, 重写后的路径的正则

- RewritePath=/foo/(?<segment>.*), /$\{segment}

重写请求路径。如上配置,访问 /foo/bar 会将路径改为/bar 再转发,也就是会转发到 https://example.org/bar 。需要注意的是,由于YAML语法,需用$\ 替换 $ 。

15 RewriteResponseHeader GatewayFilter Factory

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

如果名为 X-Response-Foo 的响应头的内容是/42?user=ford&password=omg!what&flag=true,则会被修改为/42?user=ford&password=***&flag=true。

16 SaveSession GatewayFilter Factory

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

在转发到后端微服务请求之前,强制执行 WebSession::save 操作。用在那种像 Spring Session 延迟数据存储(笔者注:数据不是立刻持久化)的,并希望在请求转发前确保session状态保存情况。

如果你将Spring Secutiry于Spring Session集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。

17 SecureHeaders GatewayFilter Factory

添加一系列起安全作用的响应头。Spring Cloud Gateway参考了这篇博客的建议:https://blog.appcanary.com/2017/http-security-headers.html

默认会添加如下Header(包括值):

?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

如果你想修改这些Header的值,可使用如下配置:

前缀:spring.cloud.gateway.filter.secure-headers

上面的header对应的后缀:

?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.xss-protection-header: 你想要的值

如果想禁用某些Header,可使用如下配置:spring.cloud.gateway.filter.secure-headers.disable ,多个用 , 分隔。例如:spring.cloud.gateway.filter.secure-headers.disable=frame-options,download-options 。

18 SetPath GatewayFilter Factory

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

采用路径template参数,通过请求路径的片段的模板化,来达到操作修改路径的母的,运行多个路径片段模板化。

如上配置,访问${GATEWAY_PATH}/foo/bar ,则对于后端微服务的路径会修改为 /bar 。

19 SetResponseHeader GatewayFilter Factory

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

如果后端服务响应带有名为 X-Response-Foo 的响应头,则将值改为替换成 Bar 。

20 SetStatus GatewayFilter Factory

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

修改响应的状态码,值可以是数字,也可以是字符串。但一定要是Spring HttpStatus 枚举类中的值。如上配置,两种方式都可以返回HTTP状态码401。

21 StripPrefix GatewayFilter Factory

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

数字表示要截断的路径的数量。如上配置,如果请求的路径为 /name/bar/foo ,则路径会修改为/foo ,也就是会截断2个路径。

22 Retry GatewayFilter Factory

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

针对不同的响应做重试,可配置如下参数:

?retries: 重试次数

?statuses: 需要重试的状态码,取值在 org.springframework.http.HttpStatus 中

?methods: 需要重试的请求方法,取值在 org.springframework.http.HttpMethod 中

?series: HTTP状态码系列,取值在 org.springframework.http.HttpStatus.Series 中

23 RequestSize GatewayFilter Factory

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

为后端服务设置收到的最大请求包大小。如果请求大小超过设置的值,则返回 413 Payload Too Large 。默认值是5M

24 Modify Request Body GatewayFilter Factory

TIPS

该过滤器处于 BETA 状态,未来API可能会变化,生产环境请慎用。

可用于在Gateway将请求发送给后端微服务之前,修改请求体内容。该过滤器只能通过代码配置,不支持在配置文件设置。示例:

@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;
 }
}

25 Modify Response Body GatewayFilter Factory

TIPS

该过滤器处于 BETA 状态,未来API可能会变化,生产环境请慎用。

可用于修改响应体内容。该过滤器只能通过代码配置,不支持在配置文件设置。示例:

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

26 Default Filters

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

如果你想为所有路由添加过滤器,可使用该属性。

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

?001:《Java并发与高并发解决方案》学习笔记;

?002:《深入JVM内核——原理、诊断与优化》学习笔记;

?003:《Java面试宝典》

?004:《Docker开源书》

?005:《Kubernetes开源书》

?006:《DDD速成(领域驱动设计速成)》


References

[1] Spring Cloud Netflix项目进入维护模式之我见: http://www.itmuch.com/spring-cloud-sum/spring-cloud-netflix-in-maintenance-mode/

[2] IETF: https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3

相关推荐

华为交换机配置命令总结

1、配置文件相关命令[Quidway]displaycurrent-configuration显示当前生效的配置[Quidway]displaysaved-configuration显示fla...

解决账户无法登录的故障
解决账户无法登录的故障

在优化系统时错误地根据网上的提示,将唯一的Administrator账户设置为禁用,导致重启后无法进入系统。类似的故障还有使用组策略限制本地账户登录,导致重启后...

2023-10-11 17:16 xiyangw

S5720交换机登录提示初始密码存在安全风险
S5720交换机登录提示初始密码存在安全风险

问题描述客户每次登录输密码时,提示初始密码不安全,现在客户嫌麻烦想要去掉:Username:huaweiPassword:Warning:Theinitia...

2023-10-11 17:15 xiyangw

Springboot,Mybatis修改登录用户的密码
Springboot,Mybatis修改登录用户的密码

一、Mybatis.xml<updateid="changePassword"parameterType="string...

2023-10-11 17:15 xiyangw

PHP理论知识之沐浴更衣重看PHP基础(二)
PHP理论知识之沐浴更衣重看PHP基础(二)

接上篇,咱们继续讲解PHP基础八、标准PHP组件和框架的数量很多,随之产生的问题就是:单独开发的框架没有考虑到与其他框架的通信。这样对开发者和框架本身都是不利的...

2023-10-11 17:15 xiyangw

新鲜出炉UCloud云主机“数据方舟”评测报告(5)— — 关其城
新鲜出炉UCloud云主机“数据方舟”评测报告(5)— — 关其城

2015年10月29日,UCloud云主机黑科技——“数据方舟”功能正式上线,首轮内测随即开放。截止至2015年12月6日,我们共收到了534位用户的评测申...

2023-10-11 17:14 xiyangw

业余无线电Q简语及英文缩语
业余无线电Q简语及英文缩语

Q简语:语音通信及CW通信通用(加粗为常用)QRA电台何台QRB电台间之距离QRG告之正确频率QRH频率是否变动QRI发送音调QRJ能否收到QRK信号之可...

2023-10-11 17:14 xiyangw

非常详细!如何理解表格存储的多版本、生命周期和有效版本偏差
非常详细!如何理解表格存储的多版本、生命周期和有效版本偏差

表格存储在8月份推出了容量型实例,直接支持了表级别最大版本号和生命周期,高性能实例也将会在9月中旬支持这两个特性。那么,最大版本号和生命周期以及特有的...

2023-10-11 17:14 xiyangw

H3C交换机恢复出厂和各种基本配置,这20个要点你知道吗?
H3C交换机恢复出厂和各种基本配置,这20个要点你知道吗?

私信“干货”二字,即可领取138G伺服与机器人专属及电控资料!H3C交换机不知道密码如何恢复出厂设置1、开机启动,Ctrl+B进入bootrom菜单,选择恢复出...

2023-10-11 17:13 xiyangw

在使用移动支付系统的时候如何保护信息安全?

移动支付的方式近年来不断被更新,使得Venmo(据嘉丰瑞德理财师了解,此为美国的“支付宝”)之类的支付方式已经可以某种意义上代替随身携带现金了。但是你必须防范那些第三方应用程序轻松地获取你的银行卡以及...

界面控件DevExpress WinForms MVVM入门指南——登录表单(下)

从本文档中,您将了解如何向应用程序添加登录表单。在本节教程中着重讨论了如何实现此任务,这基本上是附加应用程序功能的一部分。DevExpressUniversalSubscription官方最新版免...

linux基础命令(一)
linux基础命令(一)

为啥要学linux?您可能熟悉WindowsXP、Windows7、Windows10和MacOSX等操作系统。Linux就是这样一种强大的操...

2023-10-11 17:13 xiyangw

MySQL数据库密码忘记了,怎么办?

#头条创作挑战赛#MySQL数据库密码忘记了且没有其他可以修改账号密码的账户时怎么办呢?登录MySQL,密码输入错误/*密码错误,报如下错误*/[root@TESTDB~]#mysql-u...

MobaXterm忘记Session密码,如何查看已保存的密码
MobaXterm忘记Session密码,如何查看已保存的密码

MobaXterm工具登录过SSH终端后,如果存储了Session(存储后再连接ssh的时候只需要输入账号不需要输入密码就可以直接连接上ssh),则可以...

2023-10-11 17:12 xiyangw

华为交换机密码丢失修改方法
华为交换机密码丢失修改方法

华为S2300交换机找回密码设置一、目的交换机的console和telnet密码丢失,无法登录设备。交换机已进行过数据配置,要把密码恢复而数据配置不能丢失。二、...

2023-10-11 17:12 xiyangw

取消回复欢迎 发表评论: