Spring Cloud Gateway高級特性之過濾器(Hoxton版本)
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質文章,第一時間送達
1.高級特性—過濾器(Filter)
路由過濾器可用于修改進入的HTTP請求和返回的HTTP響應,路由過濾器只能指定路由進行使用。Spring Cloud Gateway 內置了多種路由過濾器,他們都由GatewayFilter的工廠類來產(chǎn)生,下面將對各個過濾器進行一一說明
Spring Cloud Gateway 內置的過濾器工廠一覽表如下:
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長按上方微信二維碼?2 秒
1.1 AddRequestHeader GatewayFilter
通過配置name和value可以增加請求的header。
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?給請求增加Header?X-Request-red
????????????#?訪問http://localhost:9100/provider/demo/hello->?eureka-client-provider/demo/hello
????????????-?AddRequestHeader=X-Request-red,?blue
請求http://localhost:9100/provider/demo/hello ,我們可以從后端獲取到添加的header頭
1.2 AddRequestParameter GatewayFilter
通過配置name和value可以增加請求的參數(shù)
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?給請求增加參數(shù)name
????????????#?訪問http://localhost:9100/provider/demo/feign?->?eureka-client-provider/demo/feign
????????????-?AddRequestParameter=name,?Trazen
通過請求http://localhost:9100/provider/demo/feign ,相當于http://localhost:9100/provider/demo/feign?name=Trazen
1.3 AddResponseHeader GatewayFilter
AddResponseHeader GatewayFilter Factory通過配置name和value可以增加響應的header。
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?給請求增加響應的header
????????????#?訪問http://localhost:9100/provider/demo/hello->?eureka-client-provider/demo/hello
????????????-?AddResponseHeader=X-Response-Foo,?Bar
通過請求http://localhost:9100/provider/demo/hello 可以看到返回的header中帶有配置的值。
1.4 DedupeResponseHeader GatewayFilter
剔除重復的響應頭。
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#剔除重復的響應頭
????????????-?DedupeResponseHeader=Access-Control-Allow-Credentials?Access-Control-Allow-Origin,?RETAIN_FIRST
例如:
我們在Gateway以及微服務上都設置了CORS(解決跨域)header,如果不做任何配置,請求 -> 網(wǎng)關 -> 微服務,獲得的響應就是這樣的:
Access-Control-Allow-Credentials:?true,?true
Access-Control-Allow-Origin:?https://hxmec.com,?https://hxmec.com
也就是Header重復了。要想把這兩個Header去重,只需設置成如下即可。
filters:
-?DedupeResponseHeader=Access-Control-Allow-Credentials?Access-Control-Allow-Origin
也就是說,想要去重的Header如果有多個,用空格分隔即可;
去重策略:
RETAIN_FIRST: 默認值,保留第一個值
RETAIN_LAST: 保留最后一個值
RETAIN_UNIQUE: 保留所有唯一值,以它們第一次出現(xiàn)的順序保留
1.5 Hystrix GatewayFilter
Hystrix 過濾器允許你將斷路器功能添加到網(wǎng)關路由中,使你的服務免受級聯(lián)故障的影響,并提供服務降級處理。
要開啟斷路器功能,我們需要在pom.xml中添加Hystrix的相關依賴:
?org.springframework.cloud
?spring-cloud-starter-netflix-hystrix
然后添加相關服務降級的處理類:
@RestController
public?class?FallbackController?{
????@GetMapping("/fallback")
????public?Object?fallback()?{
????????Map?result?=?new?HashMap<>(3);
????????result.put("data",null);
????????result.put("message","request?fallback!!!");
????????result.put("code",500);
????????return?result;
????}
}
在application-filter.yml中添加相關配置,當路由出錯時會轉發(fā)到服務降級處理的控制器上:
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????-?name:?Hystrix
??????????????args:
????????????????name:?fallbackcmd
????????????????fallback-uri:?forward:/fallback
重新啟動網(wǎng)關后停止spring-cloud-eureka-client-provider服務,再請求http://localhost:9100/provider/demo/hello 。可以看到已經(jīng)返回服務降級后的處理信息。
1.6 Spring Cloud CircuitBreaker GatewayFilter
Spring Cloud CircuitBreaker GatewayFilter 工廠使用 Spring Cloud CircuitBreaker APIs 將 Gateway 路由包裝在熔斷器中(circuit breaker)。
??Spring Cloud CircuitBreaker 支持可與 Spring Cloud Gateway 一起使用的兩個庫 Hystrix 和 Resilience4J。由于Netflix 已將 Hystrix 置于僅維護模式,因此建議使用 Resilience4J。
??要啟用 Spring Cloud CircuitBreaker,需要引入 spring-cloud-starter-circuitbreaker-reactor-resilience4j 或 spring-cloud-starter-netflix-hystrix 依賴。配置如下示例:
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?circuitbreaker_route
????????uri:?https://example.org
????????filters:
????????-?CircuitBreaker=myCircuitBreaker
1.7 FallbackHeaders GatewayFilter
允許在轉發(fā)到外部應用程序中的 fallbackUri的請求頭中添加 Hystrix或Spring Cloud CircuitBreaker執(zhí)行異常詳細信息。
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
在這個例子中,當請求lb://ingredients降級后,F(xiàn)allbackHeadersfilter會將HystrixCommand的異常信息,通過Test-Header帶給http://localhost:9994服務。
你也可以使用默認的header,也可以像上面一下配置修改header的名字:
executionExceptionTypeHeaderName (“Execution-Exception-Type”)
executionExceptionMessageHeaderName (“Execution-Exception-Message”)
rootCauseExceptionTypeHeaderName (“Root-Cause-Exception-Type”)
rootCauseExceptionMessageHeaderName (“Root-Cause-Exception-Message”)
1.8 MapRequestHeader GatewayFilter
輸入兩個參數(shù):Header1、Header2,將上游 Header1 的值賦值到下游 Header2
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?將上游?X-Request-Foo?Header?的值賦值到下游?X-Request-red中,如果輸入標頭不存在,則過濾器不起作用。如果新的命名標頭已經(jīng)存在,則其值將使用新值進行擴充。
????????????#?訪問http://localhost:9100/provider/demo/feign?->?eureka-client-provider/demo/feign
????????????-?MapRequestHeader=X-Request-Foo,?X-Request-red
通過請求http://localhost:9100/provider/demo/feign 可以看到在下游服務中,成功獲取到Header。

1.9 PrefixPath GatewayFilter
在請求路徑中添加前綴路徑
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?prefixpath_route
????????uri:?https://example.org
????????filters:
????????-?PrefixPath=/mypath
這會將/mypath作為所有匹配請求的路徑的前綴。因此,對/hello的請求將發(fā)送到/mypath/hello。
1.10 PreserveHostHeader GatewayFilter
留原始請求的host頭信息,并原封不動的轉發(fā)出去,而不是被gateway的http客戶端重置。
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?保留原始請求的host頭信息,并原封不動的轉發(fā)出去,而不是被gateway的http客戶端重置。
????????????-?PreserveHostHeader
設置了 PreserveHostHeader過濾器,過濾器會把 ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE = true保存到 ServerWebExchange的屬性中(attributes:是個 Map 結構)。在 NettyRoutingFilter 過濾器中,會取出該屬性,判斷值為 true,就取出原始請求頭中的 Host 添加進新的請求(request)中。
1.11 RequestRateLimiter GatewayFilter
RequestRateLimiter使用RateLimiter實現(xiàn)是否允許繼續(xù)執(zhí)行當前請求。如果不允許繼續(xù)執(zhí)行,則返回HTTP 429 - Too Many Requests (默認情況下)。
RequestRateLimiter GatewayFilter可以使用一個可選參數(shù)keyResolver來做速率限制。
keyResolver是KeyResolver接口的一個實現(xiàn)bean,在配置里面,通過SpEL表達式#{@myKeyResolver}來管理bean的名字myKeyResolver。
KeyResolver.java.
public?interface?KeyResolver?{
?Mono?resolve(ServerWebExchange?exchange);
}
KeyResolver 接口允許可插拔策略派生用于限制請求的密鑰。在未來的里程碑版本中,將有一些 KeyResolver 實現(xiàn)。
KeyResolver 的默認實現(xiàn)是 PrincipalNameKeyResolver,它會從 ServerWebExchange檢索 Principal并調用 Principal.getName()。
默認情況下,如果 KeyResolver 找不到 Key,請求就會被拒絕。也可以通過設置來調整此行為:
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key=true|flase
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code=
RequestRateLimiterGatewayFilterFactory.java
/**
?*?Switch?to?deny?requests?if?the?Key?Resolver?returns?an?empty?key,?defaults?to?true.
?*/
private?boolean?denyEmptyKey?=?true;
/**?HttpStatus?to?return?when?denyEmptyKey?is?true,?defaults?to?FORBIDDEN.?*/
private?String?emptyKeyStatusCode?=?HttpStatus.FORBIDDEN.name();
注意:RequestRateLimiter 不支持快捷方式的配置。下面示例的配置是無效的:
application.properties
#?INVALID?SHORTCUT?CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2,?2,?#{@userkeyresolver}
1.11.1 Redis RateLimiter
Redis RateLimiter 的實現(xiàn)是基于在 Stripe 完成的工作。它需要引入 spring-boot-starter-data-redis-reactive Spring Boot starter 包。
算法使用的是令牌桶算法(Token Bucket Algorithm)
redis-rate-limiter.replenishRate 屬性:允許每秒可以處理的請求數(shù),沒有任何丟棄的請求。該值是令牌桶的流入速率。
redis-rate-limiter.burstCapacity 屬性:允許在一秒內執(zhí)行的最大請求數(shù)。該值是令牌桶持有的令牌數(shù)。設置值為 0 將阻止所有請求。
redis-rate-limiter.requestedTokens 屬性:一個請求需要消費的令牌數(shù)。這是每個請求從 bucket 中獲取的令牌數(shù),默認為 1。
通過設置 replenishRate 和 burstCapacity 相同的值可以實現(xiàn)固定的速率。通過將burstCapacity設置為高于 replenishRate,可以允許臨時突發(fā)請求流量。
注意:兩次突發(fā)流量應間隔一段時間,以便于令牌桶中有多余的令牌供突發(fā)請求使用,若是連續(xù)的突發(fā)流量,令牌耗盡則會丟棄請求(返回 HTTP 429 - Too Many Request)。下面列了 redis-rate-limiter 的配置。
具體配置如下:
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????-?name:?RequestRateLimiter
??????????????args:
????????????????redis-rate-limiter.replenishRate:?10
????????????????redis-rate-limiter.burstCapacity:?20
????????????????redis-rate-limiter.requestedTokens:?1
配置示例:令牌產(chǎn)生速度是每秒 10 個,桶中可保存 20 個令牌(能處理的突發(fā)請求數(shù),下一秒則只能處理 10 個請求),每個請求消耗 1 個令牌。
如果設置 replenishRate=1,requestedTokens=60,burstCapacity=60,將導致每分鐘只能處理 1 個請求(1 request/min)。因為一個請求消耗 60 個令牌,生成 60 個令牌需要 1 分鐘。
KeyResolver 的 Java 配置:
@Bean
KeyResolver?userKeyResolver()?{
????//一個獲取請求參數(shù)?user?的簡單方法
????return?exchange?->?Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
也可以定義一個實現(xiàn) RateLimiter接口的限流器,并注冊為 Bean。配置中,可引用使用了 SpEL 的 Bean 名。#{@RateLimiter} 是一個 SpEL 表達式,引用名為 myRateLimiter 的 Bean。
下面配置定義了一個使用上面定義的 keyrolver 的速率限流器:
配置如下:
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????-?name:?RequestRateLimiter
??????????????args:
????????????????rate-limiter:?"#{@myRateLimiter}"
????????????????key-resolver:?"#{@userKeyResolver}"
1.12 RedirectTo GatewayFilter
輸入兩個參數(shù):Status Code、URL,將在 Response 中把 URL 賦值給 Location 屬性
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?配置成HTTP狀態(tài)碼,?URL的形式
????????????-?RedirectTo=302,?http://www.hxmec.com
HTTP狀態(tài)碼應該是HTTP狀態(tài)碼300序列,例如301
URL必須是合法的URL,并且該值會作為名為 Location 的Header。
通過測試請求/provider/demo/hello會重定向到http://www.hxmec.com
1.13 RemoveRequestHeader GatewayFilter
移除請求頭
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?移除名稱為X-Request-Foo的請求頭
????????????-?RemoveRequestHeader=X-Request-Foo
通過請求http://localhost:9100/provider/demo/hello 測試如下

1.14 RemoveResponseHeader GatewayFilter
移除響應頭
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?移除名稱為X-Response-Bar響應頭
????????????-?RemoveResponseHeader=X-Response-Bar
通過請求http://localhost:9100/provider/demo/hello ,可以發(fā)現(xiàn)在服務中添加的響應頭,已經(jīng)被去除了

1.15 RemoveRequestParameter GatewayFilter
移除請求參數(shù)
spring:
??cloud:
????gateway:
??????routes:
????????-?id:?eureka-client-provider?#路由的ID
??????????uri:?lb://eureka-client-provider
??????????predicates:
????????????-?Path=/provider/**?#?路由規(guī)則
??????????filters:
????????????-?StripPrefix=1
????????????#?移除請求名為name參數(shù)
????????????-?RemoveRequestParameter=name
通過請求http://localhost:9100/provider/demo/hello?name=Trazen ,可以看到請求中的參數(shù)在后端服務中無法獲取,在gateway中已經(jīng)去除。

1.16 RewritePath GatewayFilter
重寫路徑
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?rewritepath_route
????????uri:?https://hxmec.com
????????predicates:
????????-?Path=/foo/**
????????filters:
????????#?配置成原始路徑正則,?重寫后的路徑的正則
????????-?RewritePath=/foo/(?.*),?/$\{segment}
如上配置,訪問 /foo/bar 會將路徑改為/bar 再轉發(fā),也就是會轉發(fā)到 https://example.org/bar 。需要注意的是,由于YAML語法,需用$\ 替換 $。
1.17 RewriteLocationResponseHeader GatewayFilter
重寫響應頭中 Location 的值,通常是為了擺脫后端特定的細節(jié),使用 stripVersionMode, locationHeaderName, hostValue 和 protocolsRegex 參數(shù)來接收值。
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?rewritelocationresponseheader_route
????????uri:?http://hxmec.com
????????filters:
????????-?RewriteLocationResponseHeader=AS_IN_REQUEST,?Location,?,
如上所示,一個請求 POST api.anoyi.com/some/object/name, Response header Location 的值 prod.anoyi.com/v2/some/object/id 將被改為 api.anoyi.com/some/object/id
參數(shù) stripVersionMode 可選值如下:
NEVER_STRIP:版本信息不會被剝離,即使原始請求路徑不包含版本
AS_IN_REQUEST:僅當原始請求路徑不包含任何版本時,才會剝離版本【默認】
ALWAYS_STRIP:即使原始請求路徑包含版本,也會剝離版本
參數(shù) hostValue,如果提供,會替換 Response Header Location 值中的 host:port 部分;如果不提供,則會使用 Request 的 Host 作為默認值
參數(shù) protocolRegex,協(xié)議會與該值匹配,如果不匹配,過濾器不回做任何操作,默認值 http|https|ftp|ftps
1.18 RewriteResponseHeader GatewayFilter
重寫響應頭,使用 name, regexp 和 replacement 參數(shù)接收值。使用 Java 正則表達式提供一種靈活的方式來重寫響應頭中的值。
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?rewriteresponseheader_route
????????uri:?https://hxmec.com
????????filters:
????????-?RewriteResponseHeader=X-Response-Red,?,?password=[^&]+,?password=***
示例中,一個頭的值為 /42?user=ford&password=omg!what&flag=true,在發(fā)出下游請求后,將此頭設置為 /42?user=ford&password=***&flag=true。注意使用 $\ 代表 $,這是 YAML 格式指定的。
1.19 SaveSession GatewayFilter
保存 Session,在向下游服務轉發(fā)請求之前強制執(zhí)行 WebSession::save操作
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?save_session
????????uri:?http://www.hxmec.com
????????predicates:
????????-?Path=/foo/**
????????filters:
????????-?SaveSession
如果將 Spring Security 與 Spring Session 集成,并希望確保安全性詳細信息已轉發(fā)到遠程進程,那么這一點至關重要。
1.20 SecureHeaders GatewayFilter
SecureHeaders會向響應添加多個頭數(shù)據(jù),主要是根據(jù)這篇博客的建議:Everything you need to know about HTTP security headers。
會添加下面這些頭,括號中是默認值。
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命名空間中設置適當?shù)闹怠O旅孢@些屬性可設置: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
這些屬性是與上面列出要添加的頭是對應的,在 SecureHeadersProperties.java 安全頭屬性類文件中可以看到。
要禁用默認值,設置spring.cloud.gateway.filter.secure-headers.disable屬性,值使用逗號分隔符(,)。注意,值必須是安全標頭(secure headers)的小寫全名。如下所示:
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
1.21 SetPath GatewayFilter
輸入一個參數(shù):template,匹配 Spring Framework URI 路徑模板并修改,允許多個匹配
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?setpath_route
????????uri:?http://www.hxmec.com
????????predicates:
????????-?Path=/foo/{segment}
????????filters:
????????-?SetPath=/{segment}
如上所示,請求 /foo/bar 會被設置為 /bar 到下游
1.22 SetRequestHeader GatewayFilter
SetRequestHeader重置請求頭的值,使用 name 和 value 參數(shù)接收值
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?setrequestheader_route
????????uri:?https://www.hxmec.com
????????filters:
????????-?SetRequestHeader=X-Request-Foo,?Bar
與 AddRequestHeader GatewayFilter Factory 不同的是,這是替換 Header 而不是添加
1.23 SetResponseHeader GatewayFilter
重置響應頭中的值,使用 name 和 value參數(shù)接收值
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?setresponseheader_route
????????uri:?http://www.google.com
????????filters:
????????-?SetResponseHeader=X-Response-Foo,?Bar
對于上面的例子,如果下游的返回帶有頭信息為X-Response-Foo:1234 ,則會gateway會替換為X-Response-Foo:Bar ,在返回給客戶端。
1.24 SetStatus GatewayFilter
設置響應頭的 HTTP 編碼,使用單個參數(shù) status 接收。值必須是一個有效的 HttpStatus
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?setstatusstring_route
????????uri:?http://www.hxmec.com
????????filters:
????????-?SetStatus=BAD_REQUEST
??????-?id:?setstatusint_route
????????uri:?http://www.hxmec.com
????????filters:
????????-?SetStatus=401
此示例,設置響應的 HTTP status 為 401。
可以配置 SetStatus GatewayFilter,以在響應的頭中從代理請求返回原始 HTTP 狀態(tài)代碼。如果配置了以下屬性,則會將頭添加到響應中:
spring:
??cloud:
????gateway:
??????set-status:
????????original-status-header-name:?original-http-status
1.25 StripPrefix GatewayFilter
通過配置parts來表示截斷路徑前綴的數(shù)量
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?nameRoot
????????uri:?http://hxmec.com
????????predicates:
????????-?Path=/name/**
????????filters:
????????-?StripPrefix=2
如上面例子中,如果請求的路徑為/name/bar/foo,則路徑會修改為/foo,即將路徑的兩個前綴去掉了。
1.26 Retry GatewayFilter
該過濾器用于重試請求,支持如下參數(shù)的配置:
retries: 重試的次數(shù)
statuses: 應被重試的 HTTP Status Codes,參考 org.springframework.http.HttpStatus
methods: 應被重試的 HTTP Methods,參考org.springframework.http.HttpMethod
series: 應被重試的 Status Codes 系列,參考 org.springframework.http.HttpStatus.Series
exceptions: 應被重試的異常列表
backoff: 為重試配置指數(shù)級的 backoff。重試時間間隔的計算公式為 firstBackoff * (factor ^ n),n 是重試的次數(shù);如果設置了 maxBackoff,最大的 backoff 限制為 maxBackoff. 如果 basedOnPreviousValue 設置為 true, backoff 計算公式為 prevBackoff * factor.
如果 Retry filter 啟用,默認配置如下:retries?—?3 times
series?—?5XX series
methods?—?GET method
exceptions?—?IOException and TimeoutException
backoff?—?disabled
以下是 Retry GatewayFilter 配置示例:
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
上面例子,當下游服務返回502狀態(tài)碼時,gateway會重試3次。
注意:當將重試過濾器與帶有forward:前綴的 URL 一起使用時,應仔細編寫目標端點,以便在發(fā)生錯誤的情況下,它不會做任何可能導致響應發(fā)送到客戶端并提交的操作。例如,如果目標端點是帶注釋的控制器,則目標控制器方法不應返回帶有錯誤狀態(tài)代碼的 ResponseEntity。相反,它應該引發(fā) Exception 或發(fā)出錯誤信號(例如,通過Mono.error(ex)返回值),可以配置重試過濾器來進行重試處理。
警告:當將重試過濾器與任何帶有 body 的 HTTP方法一起使用時,body 將被緩存,并且網(wǎng)關將受到內存的限制。body 將緩存在 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR定義的請求屬性中,對象的類型是org.springframework.core.io.buffer.DataBuffer。
1.27 RequestSize GatewayFilter
當請求大小大于限制時,RequestSize 網(wǎng)關過濾器工廠可以限制請求到達下游服務。
過濾器使用maxSize參數(shù)。maxSize 是一個 DataSize類型,因此值(value)可以定義為數(shù)字,后跟可選的DataUnit 后綴,例如 KB 或 MB。默認是 B代表字節(jié)。它是請求的允許大小限制,以字節(jié)為單位。配置如下所示:
spring:
??cloud:
????gateway:
??????routes:
??????-?id:?request_size_route
????????uri:?http://localhost:8080/upload
????????predicates:
????????-?Path=/upload
????????filters:
????????-?name:?RequestSize
??????????args:
????????????maxSize:?5000000
當請求因大小而被拒絕時,RequestSize GatewayFilter 工廠將響應狀態(tài)設置為 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
注意:如果未在路由定義中作為篩選器參數(shù)提供,則默認請求大小設置為 5 MB。
1.28 SetRequestHost GatewayFilter
用指定的值替換現(xiàn)有的host header
pring:
??cloud:
????gateway:
??????routes:
??????-?id:?set_request_host_header_route
????????uri:?http://localhost:8080/headers
????????predicates:
????????-?Path=/headers
????????filters:
????????-?name:?SetRequestHost
??????????args:
????????????host:?hxmec.com
SetRequestHost GatewayFilter 工廠用 hxmec.com 替換主機頭的值
1.29 ModifyRequestBody GatewayFilter
修改請求主體,然后將其由網(wǎng)關向下游發(fā)送。
只能使用 Java DSL 來配置此過濾器。如下示例:
@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;
????}
}
1.30 ModifyResponseBody GatewayFilter
在響應發(fā)送會客戶端之前,對響應體進行修改。同樣也只支持Java配置
@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();
}
1.31 Default Filters
如果想添加一個過濾器去應用在所有的路由上,可以使用 spring.cloud.gateway.default-filters 來配置,這個屬性接收一個Filter列表。
spring:
??cloud:
????gateway:
??????default-filters:
??????-?AddResponseHeader=X-Response-Default-Foo,?Default-Bar
??????-?PrefixPath=/httpbin
2.參考文檔
【官方文檔】https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/#the-weight-route-predicate-factory
版權聲明:本文為博主原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/tuyong1972873004/article/details/107123254/
感謝點贊支持下哈?
