javascript
Spring Cloud Gateway(一)为什么用网关、能做什么、为什么选择Gateway、谓词工厂、过滤器配置
1、為什么用網(wǎng)關(guān)?能做什么?為什么選擇Gateway?
1.1、為什么用網(wǎng)關(guān)
網(wǎng)關(guān)api:封裝了系統(tǒng)內(nèi)部架構(gòu),為每個客戶端提供一個定制的 API。在微服務(wù)架構(gòu)中,服務(wù)網(wǎng)關(guān)的核心要點是,所有的客戶端和消費端都通過統(tǒng)一的網(wǎng)關(guān)接入微服務(wù),在網(wǎng)關(guān)層處理所有的非業(yè)務(wù)功能。
1.2、能做什么
服務(wù)網(wǎng)關(guān)在完成客戶端與服務(wù)器端報文格式轉(zhuǎn)換的同時,它可能還具有身份驗證、監(jiān)控、緩存、請求管理、靜態(tài)響應(yīng)處理等功能。另一方面,也可以在網(wǎng)關(guān)層制定靈活的路由策略。針對一些特定的 API,我們需要設(shè)置白名單、路由規(guī)則等各類限制
Spring Cloud Gateway是專為為網(wǎng)關(guān)的角色而設(shè)計的,功能強大,而且是官方出品
1.3、為什么選擇Gateway/Gateway特征功能
-
能夠匹配任何請求屬性上的路由;
-
謂詞和過濾器特定于路由;
-
Hystrix、sentinel集成;
-
Spring Cloud DiscoveryClient的集成
-
易于編寫的謂詞和過濾器;
-
請求速率限制;
-
路徑改寫;
2、簡介
Spring Cloud Gateway是Spring Cloud官方推出的第二代網(wǎng)關(guān)框架,取代Zuul網(wǎng)關(guān)(1.0不再維護了,2.0不再集成)。基于Spring5.0+SpringBoot2.0+WebFlux(高性能的Reactor模式響應(yīng)式通信框架Netty,異步非阻塞),性能高于zuul 1.0,提供一種簡單而高效的方法來將請求路由到API。網(wǎng)關(guān)作為流量的入口,在微服務(wù)系統(tǒng)中有著非常作用,網(wǎng)關(guān)常見的功能有路由轉(zhuǎn)發(fā)、權(quán)限校驗、限流控制等作用。
spring cloud gateway至少要求JDK8(函數(shù)式編程);
Spring Cloud Gateway工作流程
3、項目創(chuàng)建
gitee項目地址,可下載查看
- jar
- yaml
3.1、參數(shù)說明
-
Route:網(wǎng)關(guān)的基本構(gòu)建塊。 它由id,目標(biāo)uri,predicates集合和filters集合定義。 如果聚合謂詞為true,則匹配路由。
-
Predicate:這是Java 8函數(shù)謂詞。 輸入類型是Spring Framework ServerWebExchange。 這使您可以匹配HTTP請求中的所有內(nèi)容,例如標(biāo)頭或參數(shù)。
-
Filter:這些是已通過特定工廠構(gòu)造的GatewayFilter實例。 在這里,您可以在發(fā)送下游請求之前或之后修改請求和響應(yīng)。
官方文檔中有如下內(nèi)容,非常強大
1.如何包括Spring Cloud Gateway
2.詞匯表
3.工作原理
4.配置路由謂詞工廠和網(wǎng)關(guān)過濾工廠
5.路由謂詞工廠
6. GatewayFilter工廠
7.全局過濾器
8. HttpHeadersFilters
9. TLS和SSL
10.配置
11.路由元數(shù)據(jù)配置
12. Http超時配置
13. Reactor Netty訪問日志
14. CORS配置
15.執(zhí)行器API
16.故障排除
17.開發(fā)人員指南
18.使用Spring MVC或Webflux構(gòu)建一個簡單的網(wǎng)關(guān)
19.配置屬性
4、路線謂詞工廠
Spring Cloud Gateway將路由匹配作為Spring WebFlux HandlerMapping基礎(chǔ)架構(gòu)的一部分。 Spring Cloud Gateway包括許多內(nèi)置的路由謂詞工廠。 所有這些謂詞都與HTTP請求的不同屬性匹配。 您可以將多個路由謂詞工廠與邏輯和語句結(jié)合使用。
datetime(這是一個Java ZonedDateTime)。
- 時區(qū)生成:2019-09-15T20:58:18.786182+08:00[Asia/Shanghai]public static void main(String[] args) {ZonedDateTime zbj = ZonedDateTime.now(); // 默認(rèn)時區(qū)System.out.println(zbj); }
官網(wǎng)copy的謂詞工廠如下
4.1、After路由謂詞工廠
該謂詞匹配在指定日期時間之后發(fā)生的請求。
以下示例配置了路由后謂詞:
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]4.2、Before由謂詞工廠
匹配在指定日期時間之前發(fā)生的請求
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]4.3、Between 路徑謂詞工廠
此謂詞匹配發(fā)生在datetime1之后和datetime2之前的請求。datetime2參數(shù)必須在datetime1之后。
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]4.4、Cookie路由謂詞工廠
Cookie路由謂詞工廠接受兩個參數(shù),Cookie名稱和regexp(這是一個Java正則表達(dá)式)。
此謂詞匹配具有給定名稱且其值與正則表達(dá)式匹配的Cookie。
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, \d+4.5、Header 路由謂詞工廠
標(biāo)頭路由謂詞工廠使用兩個參數(shù),標(biāo)頭名稱和一個regexp(這是Java正則表達(dá)式)。
該謂詞與具有給定名稱的 header匹配,該header 的值與正則表達(dá)式匹配。
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+4.6、Host 路由謂詞工廠
主機路由謂詞工廠接受一個參數(shù):主機名模式列表。","作為分隔符。匹配請求接口的url路徑是否合法
該謂詞匹配匹配模式的主機頭,,支持通配符
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org4.7、 Method 路由謂詞工廠
接受一個methods參數(shù)
該參數(shù)是一個或多個參數(shù):要匹配的HTTP方法
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST4.8、Path 路由謂詞工廠
路徑謂詞工廠有兩個參數(shù):Spring PathMatcher模式列表和一個名為matchTrailingSlash(默認(rèn)為true)的可選標(biāo)志。以下示例配置路徑謂詞:
matchTrailingSlash :是否匹配末尾"/"
``
4.9、Query 路由謂詞工廠
查詢路由謂詞工廠有兩個參數(shù):一個必需的參數(shù)和一個可選的regexp(這是一個Java正則表達(dá)式)
請求的參數(shù)中是否含有某個值
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree.4.10、RemoteAddr 路由謂詞工廠
遠(yuǎn)程調(diào)用地址 路由謂詞工廠獲取源的列表(最小大小1),這些源是CIDR表示法(IPv4或IPv6)字符串
例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子網(wǎng)掩碼)
如果請求的遠(yuǎn)程地址是192.168.1.10,則此路由匹配。
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/244.11、 路由謂詞工廠
權(quán)重路由謂詞工廠有兩個參數(shù):group和Weight(int)。每組計算權(quán)重。
請求分流
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 25、過濾器配置
路由過濾器允許以某種方式修改傳入的HTTP請求或傳出HTTP響應(yīng)。路由過濾器的作用域是特定的路由。SpringCloudGateway包含許多內(nèi)置網(wǎng)關(guān)過濾器工廠。
官網(wǎng)copy的網(wǎng)關(guān)過濾器工廠如下
5.1、AddRequestHeader網(wǎng)關(guān)過濾器工廠
添加請求頭:AddRequestHeader 網(wǎng)關(guān)過濾器工廠采用名稱和值參數(shù)。
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestHeader=X-Request-red, blueURI變量可以在值中使用,并在運行時展開
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- AddRequestHeader=X-Request-Red, Blue-{segment}5.2、AddRequestParameter 網(wǎng)關(guān)過濾器工廠
添加請求參數(shù):采用名稱和值參數(shù)
spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blueURI變量可以在值中使用,并在運行時展開
spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- AddRequestParameter=foo, bar-{segment}5.3、AddResponseHeader 網(wǎng)關(guān)過濾器工廠
添加相應(yīng)頭
spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgfilters:- AddResponseHeader=X-Response-Red, BlueURI變量可以在值中使用,并在運行時展開。
spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- AddResponseHeader=foo, bar-{segment}5.4、DedupeResponseHeader網(wǎng)關(guān)過濾器工廠
刪除重復(fù)響應(yīng)頭:采用名稱參數(shù)和可選策略參數(shù)。名稱可以包含以空格分隔的標(biāo)題名稱列表。
可選的 strategy 參數(shù):RETAIN_FIRST(默認(rèn),先保留)、RETAIN_LAST(后保留)、RETAIN_UNIQUE(唯一保留).
5.5、Spring Cloud CircuitBreaker 網(wǎng)關(guān)過濾器工廠
Spring Cloud CircuitBreaker 網(wǎng)關(guān)過濾器工廠使用Spring Cloud CircuitBreaker API將網(wǎng)關(guān)路由包裝在斷路器中。 Spring Cloud CircuitBreaker支持多個可與Spring Cloud Gateway一起使用的庫。 Spring Cloud開箱即用地支持Resilience4J。
要啟用Spring Cloud CircuitBreaker過濾器,您需要在類路徑上放置spring-cloud-starter-circuitbreaker-reactor-resilience4j。
spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: https://example.orgfilters:- CircuitBreaker=myCircuitBreaker要配置斷路器,請參閱所使用的基礎(chǔ)斷路器實現(xiàn)的配置。
Resilience4J文檔
Spring Cloud CircuitBreaker過濾器還可以接受可選的fallbackUri參數(shù)。 當(dāng)前,僅支持轉(zhuǎn)發(fā):計劃的URI。 如果調(diào)用了后備,則請求將轉(zhuǎn)發(fā)到與URI匹配的控制器。 以下示例配置了這種后備:
spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint5.6、FallbackHeaders 網(wǎng)關(guān)過濾器工廠
FallbackHeaders工廠使您可以在轉(zhuǎn)發(fā)到外部應(yīng)用程序中的fallbackUri的請求的標(biāo)頭中添加Spring Cloud CircuitBreaker執(zhí)行異常詳細(xì)信息,如以下情況所示:
spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallbackfilters:- name: FallbackHeadersargs:executionExceptionTypeHeaderName: Test-Header在此示例中,在運行斷路器時發(fā)生執(zhí)行異常之后,該請求將轉(zhuǎn)發(fā)到在localhost:9994上運行的應(yīng)用程序中的回退端點或處理程序。 FallbackHeaders過濾器將具有異常類型,消息和(如果有)根本原因異常類型和消息的標(biāo)頭添加到該請求。
您可以通過設(shè)置以下參數(shù)的值(以其默認(rèn)值顯示)來覆蓋配置中標(biāo)頭的名稱:
executionExceptionTypeHeaderName ("Execution-Exception-Type")executionExceptionMessageHeaderName ("Execution-Exception-Message")rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")有關(guān)斷路器和網(wǎng)關(guān)的更多信息,請參見Spring Cloud CircuitBreaker Factory部分。
5.7、MapRequestHeader 網(wǎng)關(guān)過濾器工廠
MapRequestHeader 網(wǎng)關(guān)過濾器工廠采用fromHeader和toHeader參數(shù)。它創(chuàng)建一個新的命名頭(toHeader),并從傳入http請求的現(xiàn)有命名頭(fromHeader)中提取該值。如果輸入標(biāo)頭不存在,則篩選器沒有影響。如果新的命名頭已經(jīng)存在,則其值將用新值進行擴充。以下示例配置MapRequestHeader:
spring:cloud:gateway:routes:- id: map_request_header_routeuri: https://example.orgfilters:- MapRequestHeader=Blue, X-Request-Red這會將X-Request-Red:標(biāo)頭添加到下游請求中,并帶有來自傳入HTTP請求的Blue標(biāo)頭的更新值。
5.8、PrefixPath 網(wǎng)關(guān)過濾器工廠
采用單個前綴參數(shù)
這將把/mypath作為所有匹配請求的路徑的前綴。因此對/hello的請求將發(fā)送到/mypath/hello。
spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- PrefixPath=/mypath5.9、PreserveHostHeader 網(wǎng)關(guān)過濾器工廠
沒有參數(shù)。此篩選器設(shè)置路由篩選器檢查的請求屬性,以確定是否應(yīng)發(fā)送原始主機標(biāo)頭,而不是HTTP客戶端確定的主機標(biāo)頭。
spring:cloud:gateway:routes:- id: preserve_host_routeuri: https://example.orgfilters:- PreserveHostHeader5.10、RequestRateLimiter 網(wǎng)關(guān)過濾器工廠
請求速率限制器
RequestRateLimiter GatewayFilter工廠使用RateLimiter實現(xiàn)來確定是否允許繼續(xù)當(dāng)前請求。 如果不是,則會返回HTTP 429-太多請求(默認(rèn)情況下)的狀態(tài)。
該過濾器采用可選的keyResolver參數(shù)和特定于速率限制器的參數(shù)(本節(jié)稍后將介紹)。
keyResolver是一個實現(xiàn)KeyResolver接口的bean。 在配置中,使用SpEL按名稱引用bean。 #{@myKeyResolver} 是一個SpEL表達(dá)式,它引用一個名為myKeyResolver的bean。 以下清單顯示了KeyResolver接口:
public interface KeyResolver {Mono<String> resolve(ServerWebExchange exchange); }KeyResolver接口允許可插拔策略派生用于限制請求的密鑰。 在未來的里程碑版本中,將有一些KeyResolver實現(xiàn)。
KeyResolver的默認(rèn)實現(xiàn)是PrincipalNameKeyResolver,它從ServerWebExchange檢索Principal并調(diào)用Principal.getName()。
默認(rèn)情況下,如果KeyResolver找不到密鑰,則拒絕請求。 您可以通過設(shè)置spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key(正確或錯誤)和spring.cloud.gateway.filter.request-rate-limiter.empty-key來調(diào)整此行為。 狀態(tài)代碼屬性。
.
.
.
更多內(nèi)容查看官網(wǎng)
5.11、RedirectTo 網(wǎng)關(guān)過濾器工廠
RedirectTo GatewayFilter工廠采用兩個參數(shù),即status和url。 status參數(shù)應(yīng)該是300系列重定向HTTP代碼,例如301。url參數(shù)應(yīng)該是有效的URL。 這是Location標(biāo)頭的值。 對于相對重定向,您應(yīng)該使用uri: no://op作為路由定義的uri。 下面的清單配置一個RedirectTo GatewayFilter:
這將發(fā)送帶有Location:https://acme.org標(biāo)頭的狀態(tài)302,以執(zhí)行重定向。
spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- RedirectTo=302, https://acme.org5.12、RemoveRequestHeader 網(wǎng)關(guān)過濾器工廠
RemoveRequestHeader GatewayFilter工廠采用名稱參數(shù)。 它是要刪除的Header的名稱。
這會在將X-Request-Foo header 發(fā)送到下游之前將其刪除。
spring:cloud:gateway:routes:- id: removerequestheader_routeuri: https://example.orgfilters:- RemoveRequestHeader=X-Request-Foo5.13、RemoveResponseHeader網(wǎng)關(guān)過濾器工廠
RemoveResponseHeader GatewayFilter工廠采用名稱參數(shù)。它是要刪除的header 的名稱。
將X-Response-Foo標(biāo)頭從響應(yīng)中刪除,然后再返回到網(wǎng)關(guān)客戶端。
spring:cloud:gateway:routes:- id: removeresponseheader_routeuri: https://example.orgfilters:- RemoveResponseHeader=X-Response-Foo要刪除任何類型的敏感header ,應(yīng)為可能要執(zhí)行此操作的任何路由配置此過濾器。 另外,您可以使用spring.cloud.gateway.default-filters一次配置此過濾器,并將其應(yīng)用于所有路由。
5.14、RemoveRequestParameter 網(wǎng)關(guān)過濾器工廠
它是要刪除的查詢參數(shù)的名稱
這將刪除red 參數(shù),然后再將其發(fā)送到下游。
spring:cloud:gateway:routes:- id: removerequestparameter_routeuri: https://example.orgfilters:- RemoveRequestParameter=red5.15、RewritePath網(wǎng)關(guān)過濾器工廠
重寫路徑網(wǎng)關(guān)過濾器工廠采用路徑regexp參數(shù)和替換參數(shù)。這使用Java正則表達(dá)式來靈活地重寫請求路徑。
對于’/red/blue’的請求路徑,這將在發(fā)出下游請求之前將路徑設(shè)置為’/blue’。
請注意,由于YAML規(guī)范,應(yīng)將$替換為$\。
5.16、RewriteLocationResponseHeader 網(wǎng)關(guān)過濾器工廠
RewriteLocationResponseHeader GatewayFilter工廠修改位置響應(yīng)頭的值,通常是為了消除后端特定的詳細(xì)信息。它使用stripVersionMode、locationHeaderName、hostValue和protocolsRegex參數(shù)。
spring:cloud:gateway:routes:- id: rewritelocationresponseheader_routeuri: http://example.orgfilters:- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,例如,對于POST api.example.com/some/object/name的請求,object-service.prod.example.net/v2/some/object/id的位置響應(yīng)標(biāo)頭值被重寫為api.example.com/some/object/id。
stripVersionMode參數(shù)具有以下可能的值:NEVER_STRIP,AS_IN_REQUEST(默認(rèn)值)和ALWAYS_STRIP。
-
NEVER_STRIP:即使原始請求路徑不包含任何版本,也不會剝離該版本。
-
AS_IN_REQUEST :僅當(dāng)原始請求路徑不包含任何版本時,才剝離該版本。
-
ALWAYS_STRIP :即使原始請求路徑包含版本,也總是剝離版本。
hostValue參數(shù)(如果提供)用于替換響應(yīng)Location標(biāo)頭的host:port部分。 如果未提供,則使用主機請求標(biāo)頭的值。
protocolRegex參數(shù)必須是一個有效的正則表達(dá)式字符串,協(xié)議名稱與該字符串匹配。 如果不匹配,則過濾器不執(zhí)行任何操作。 默認(rèn)值為http | https | ftp | ftps。
5.17、RewriteResponseHeader 網(wǎng)關(guān)過濾器工廠
RewriteResponseHeader GatewayFilter工廠采用名稱,正則表達(dá)式和替換參數(shù)。 它使用Java正則表達(dá)式以靈活的方式重寫響應(yīng)頭值。 以下示例配置RewriteResponseHeader GatewayFilter:
對于 /42?user=ford&password=omg!what&flag=true的header 值,在發(fā)出下游請求后將其設(shè)置為/42?user=ford&password=***&flag=true。
spring:cloud:gateway:routes:- id: rewriteresponseheader_routeuri: https://example.orgfilters:- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***5.18、SaveSession 網(wǎng)關(guān)過濾器工廠
SaveSession 網(wǎng)關(guān)過濾器工廠在向下游轉(zhuǎn)發(fā)呼叫之前強制執(zhí)行WebSession::save操作。 這在使用類似Spring Session的延遲數(shù)據(jù)存儲時特別有用,您需要確保在進行轉(zhuǎn)發(fā)調(diào)用之前保存了會話狀態(tài)。 以下示例配置SaveSession GatewayFilter:
如果您將Spring Security 與Spring Session 集成在一起,并希望確保安全性詳細(xì)信息已轉(zhuǎn)發(fā)到遠(yuǎn)程進程,這一點至關(guān)重要。
spring:cloud:gateway:routes:- id: save_sessionuri: https://example.orgpredicates:- Path=/foo/**filters:- SaveSession5.19、SecureHeaders 網(wǎng)關(guān)過濾器工廠
SecureHeaders GatewayFilter工廠將許多頭添加到響應(yīng)中。
添加了以下頭(以其默認(rèn)值顯示):
-
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)
要更改默認(rèn)值,請在spring.cloud.gateway.filter.secure-headers命名空間中設(shè)置適當(dāng)?shù)膶傩浴?可以使用以下屬性:
-
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
要禁用默認(rèn)值,請使用逗號分隔值設(shè)置spring.cloud.gateway.filter.secure-headers.disable屬性。 以下示例顯示了如何執(zhí)行此操作:
需要使用安全標(biāo)頭的小寫全名來禁用它。
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
5.20、SetPath網(wǎng)關(guān)過濾器工廠
SetPath GatewayFilter工廠采用路徑模板參數(shù)。 通過允許路徑的模板段,它提供了一種操作請求路徑的簡單方法。 這使用了Spring Framework中的URI模板。 允許多個匹配段。
對于/red/blue的請求路徑,這會在發(fā)出下游請求之前將路徑設(shè)置為/blue。
spring:cloud:gateway:routes:- id: setpath_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- SetPath=/{segment}5.21、SetRequestHeader 網(wǎng)關(guān)過濾器工廠
工廠采用名稱和值參數(shù)
spring:cloud:gateway:routes:- id: setrequestheader_routeuri: https://example.orgfilters:- SetRequestHeader=X-Request-Red, Blue該網(wǎng)關(guān)過濾器用給定名稱替換(而不是添加)所有headers 。 因此,如果下游服務(wù)器響應(yīng)X-Request-Red:1234,則將其替換為X-Request-Red:Blue,這是下游服務(wù)將收到的內(nèi)容。
SetRequestHeader知道用于匹配路徑或主機的URI變量。 可以在值中使用URI變量,并在運行時對其進行擴展。 以下示例配置使用變量的SetRequestHeader GatewayFilter:
spring:cloud:gateway:routes:- id: setrequestheader_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- SetRequestHeader=foo, bar-{segment}5.22、SetResponseHeader 網(wǎng)關(guān)過濾器工廠
工廠采用名稱和值參數(shù)
spring:cloud:gateway:routes:- id: setresponseheader_routeuri: https://example.orgfilters:- SetResponseHeader=X-Response-Red, Blue該GatewayFilter用給定名稱替換(而不是添加)所有標(biāo)頭。 因此,如果下游服務(wù)器使用X-Response-Red:1234進行響應(yīng),則將其替換為X-Response-Red:Blue,這是網(wǎng)關(guān)客戶端將收到的內(nèi)容。
SetResponseHeader知道用于匹配路徑或主機的URI變量。 值中可以使用URI變量,并將在運行時進行擴展。 以下示例配置使用變量的SetResponseHeader GatewayFilter:
spring:cloud:gateway:routes:- id: setresponseheader_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- SetResponseHeader=foo, bar-{segment}5.23、SetStatus 網(wǎng)關(guān)過濾器工廠
單個參數(shù)status。 它必須是有效的Spring HttpStatus。 它可以是整數(shù)值404或枚舉的字符串表示形式:NOT_FOUND。
無論哪種情況,響應(yīng)的HTTP狀態(tài)都設(shè)置為401。
spring:cloud:gateway:routes:- id: setstatusstring_routeuri: https://example.orgfilters:- SetStatus=BAD_REQUEST- id: setstatusint_routeuri: https://example.orgfilters:- SetStatus=401您可以將SetStatus GatewayFilter配置為在響應(yīng)的頭中從代理請求返回原始HTTP狀態(tài)代碼。 如果將頭配置為以下屬性,則會將其添加到響應(yīng)中:
spring:cloud:gateway:set-status:original-status-header-name: original-http-status5.24、StripPrefix 網(wǎng)關(guān)過濾器工廠
工廠采用一個參數(shù),即parts。 parts參數(shù)指示在向下游發(fā)送請求之前,要從請求中剝離的路徑中的部分?jǐn)?shù)量。
當(dāng)通過網(wǎng)關(guān)向/name/blue/red發(fā)出請求時,對nameservice的請求去除掉前面兩個前綴變?yōu)?#xff1a;nameservice/red。
spring:cloud:gateway:routes:- id: nameRooturi: https://nameservicepredicates:- Path=/name/**filters:- StripPrefix=25.25、Retry 網(wǎng)關(guān)過濾器工廠
重試GatewayFilter工廠支持以下參數(shù):
-
retries:應(yīng)嘗試的重試次數(shù)。
-
statuses:應(yīng)重試的HTTP狀態(tài)代碼,使用org.springframework.http.HttpStatus表示。
-
methods:應(yīng)重試的HTTP方法,使用org.springframework.http.HttpMethod表示。
-
series:要重試的狀態(tài)碼系列,使用org.springframework.http.HttpStatus.Series表示。
-
exceptions:應(yīng)重試的引發(fā)異常的列表。
-
backoff:為重試配置的指數(shù)補償。 在firstBackoff *(因子^ n)的退避間隔之后執(zhí)行重試,其中n是迭代。 如果配置了maxBackoff,則將應(yīng)用的最大退避限制為maxBackoff。 如果basedOnPreviousValue為true,則通過使用prevBackoff * factor計算退避量。
如果啟用了以下默認(rèn)值,則為“Retry”過濾器配置:
-
retries:3次
-
series:5XX系列
-
methods:GET方法
-
exceptions:IOException和TimeoutException
-
backoff:disabled
當(dāng)將重試過濾器與帶有前綴的轉(zhuǎn)發(fā)URL一起使用時,應(yīng)仔細(xì)編寫目標(biāo)端點,以便在發(fā)生錯誤的情況下,它不會做任何可能導(dǎo)致響應(yīng)發(fā)送到客戶端并提交的操作。 例如,如果目標(biāo)端點是帶注釋的控制器,則目標(biāo)控制器方法不應(yīng)返回帶有錯誤狀態(tài)代碼的ResponseEntity。 相反,它應(yīng)該引發(fā)Exception或發(fā)出錯誤信號(例如,通過Mono.error(ex)返回值),可以將重試過濾器配置為通過重試來處理。
當(dāng)將重試過濾器與任何具有主體的HTTP方法一起使用時,主體將被緩存,并且網(wǎng)關(guān)將受到內(nèi)存的限制。 正文緩存在ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR定義的請求屬性中。 對象的類型是org.springframework.core.io.buffer.DataBuffer。
5.26、RequestSize 網(wǎng)關(guān)過濾器工廠
當(dāng)請求大小大于允許的限制時,RequestSize GatewayFilter工廠可以限制請求到達(dá)下游服務(wù)。 過濾器采用maxSize參數(shù)。 maxSize是一種DataSize類型,因此可以將值定義為一個數(shù)字,后跟一個可選的DataUnit后綴,例如’KB’或’MB’。 字節(jié)的默認(rèn)值為“ B”。 它是請求的允許大小限制,以字節(jié)為單位。 以下清單配置了RequestSize GatewayFilter:
spring:cloud:gateway:routes:- id: request_size_routeuri: http://localhost:8080/uploadpredicates:- Path=/uploadfilters:- name: RequestSizeargs:maxSize: 5000000當(dāng)請求由于大小而被拒絕時,RequestSize GatewayFilter工廠將響應(yīng)狀態(tài)設(shè)置為413 Payload Too Large,并帶有附加的報頭errorMessage。
errorMessage:Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
如果未在路由定義中作為過濾器參數(shù)提供,則默認(rèn)請求大小將設(shè)置為5 MB。
5.27、SetRequestHostHeader網(wǎng)關(guān)過濾器工廠
在某些情況下,可能需要覆蓋主機頭。 在這種情況下,SetRequestHostHeader GatewayFilter工廠可以用指定的值替換現(xiàn)有的主機頭。 過濾器采用主機參數(shù)。 下面的清單配置了SetRequestHostHeader GatewayFilter:
spring:cloud:gateway:routes:- id: set_request_host_header_routeuri: http://localhost:8080/headerspredicates:- Path=/headersfilters:- name: SetRequestHostHeaderargs:host: example.orgSetRequestHostHeader GatewayFilter工廠用example.org替換主機頭的值。
5.28、Modify a Request Body網(wǎng)關(guān)過濾器工廠
您可以使用ModifyRequestBody篩選器篩選器來修改請求主體,然后將其由網(wǎng)關(guān)向下游發(fā)送。
以下清單顯示了如何修改請求正文GatewayFilter:
如果請求沒有正文,則RewriteFilter將傳遞為null。 應(yīng)該返回Mono.empty()以便在請求中分配丟失的正文。
@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;} }5.29、Modify a Response Body 網(wǎng)關(guān)過濾器工廠
您可以使用ModifyResponseBody篩選器在將響應(yīng)正文發(fā)送回客戶端之前對其進行修改。
只能使用Java DSL來配置此過濾器。
如果響應(yīng)沒有主體,則RewriteFilter將傳遞為null。 應(yīng)該返回Mono.empty()以便在響應(yīng)中分配丟失的主體。
@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(); }5.30、Token Relay網(wǎng)關(guān)過濾器工廠
Token Relay 是OAuth2使用者充當(dāng)客戶端并將傳入token 轉(zhuǎn)發(fā)到傳出資源請求的地方。 使用者可以是純客戶端(如SSO應(yīng)用程序)或資源服務(wù)器。
Spring Cloud Gateway可以將OAuth2訪問token 下游轉(zhuǎn)發(fā)到它正在代理的服務(wù)。 要將此功能添加到網(wǎng)關(guān),您需要添加TokenRelayGatewayFilterFactory,如下2種方式所示:
- 如java代碼@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes().route("resource", r -> r.path("/resource").filters(f -> f.tokenRelay()).uri("http://localhost:9000")).build(); }
- yaml配置spring:cloud:gateway:routes:- id: resourceuri: http://localhost:9000predicates:- Path=/resourcefilters:- TokenRelay=
并且它將(除了登錄用戶并獲取令牌之外)還將身份驗證令牌傳遞到服務(wù)(在本例中為/ resource)的下游。
要為Spring Cloud Gateway啟用此功能,請?zhí)砑右韵乱蕾図?/p>
- org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的? {githubmaster} /src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java [filter]從當(dāng)前經(jīng)過身份驗證的用戶中提取訪問令牌,并將其放入下游請求的請求標(biāo)頭中。
有關(guān)完整的工作示例,請參見此項目。
僅當(dāng)設(shè)置了適當(dāng)?shù)膕pring.security.oauth2.client.*屬性(會觸發(fā)創(chuàng)建ReactiveClientRegistrationRepository bean)時,才會創(chuàng)建TokenRelayGatewayFilterFactory bean。
TokenRelayGatewayFilterFactory使用的ReactiveOAuth2AuthorizedClientService的默認(rèn)實現(xiàn)使用內(nèi)存中的數(shù)據(jù)存儲。 如果需要更強大的解決方案,則需要提供自己的實現(xiàn)ReactiveOAuth2AuthorizedClientService。
5.31、Default過濾器
要添加過濾器并將其應(yīng)用于所有路由,可以使用spring.cloud.gateway.default-filters。 此屬性采用過濾器列表。 以下清單定義了一組默認(rèn)過濾器:
spring:cloud:gateway:default-filters:- AddResponseHeader=X-Response-Default-Red, Default-Blue- PrefixPath=/httpbin6、Global Filters全局過濾器
GlobalFilter接口與GatewayFilter具有相同的簽名。這些是有條件地應(yīng)用于所有路由的特殊篩選器。
此接口及其用法可能會在將來的迭代版本中發(fā)生更改。
6.1、組合全局過濾器和網(wǎng)關(guān)過濾器排序
當(dāng)請求與路由匹配時,篩選web處理程序?qū)⑷趾Y選器的所有實例以及網(wǎng)關(guān)篩選器的所有路由特定實例添加到篩選器鏈。此組合過濾器鏈按org.springframework.core.orderd接口,您可以通過實現(xiàn)getOrder()方法來設(shè)置它。
由于SpringCloudGateway區(qū)分了過濾器邏輯執(zhí)行的“pre”和“post”階段,優(yōu)先級最高的過濾器在“pre”(預(yù))階段是第一個,最后一個在“post”階段。
客戶端向Spring Cloud Gateway發(fā)出請求。 如果網(wǎng)關(guān)處理程序映射確定請求與路由匹配,則將其發(fā)送到網(wǎng)關(guān)Web處理程序。 該處理程序通過特定于請求的過濾器鏈來運行請求。 篩選器由虛線分隔的原因是,篩選器可以在發(fā)送代理請求之前和之后運行邏輯。 所有“pre”過濾器邏輯均被執(zhí)行。 然后發(fā)出代理請求。 發(fā)出代理請求后,將運行“post”過濾器邏輯。
以下列表配置篩選器鏈:
@Bean public GlobalFilter customFilter() {return new CustomGlobalFilter(); }public class CustomGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("custom global filter");return chain.filter(exchange);}@Overridepublic int getOrder() {return -1;} }6.2、轉(zhuǎn)發(fā)路由篩選器
ForwardRoutingFilter在交換屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。 如果URL具有轉(zhuǎn)發(fā)方案(例如forward:///localendpoint),則它將使用Spring DispatcherHandler來處理請求。 請求URL的路徑部分被轉(zhuǎn)發(fā)URL中的路徑覆蓋。 未經(jīng)修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。
6.3、負(fù)載平衡器客戶端篩選器(利用Ribbon實現(xiàn))
LoadBalancerClientFilter在名為ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的交換屬性中查找URI。 如果URL的方案為lb(例如 lb://myservice),它將使用Spring Cloud LoadBalancerClient將名稱(在本例中為myservice)解析為實際的主機和端口,并替換同一屬性中的URI。 未經(jīng)修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。 篩選器還會在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR屬性中查找其是否等于lb。如果是,則應(yīng)用相同的規(guī)則。 下面的清單配置一個LoadBalancerClientFilter:
spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/**默認(rèn)情況下,當(dāng)在LoadBalancer中找不到服務(wù)實例時,將返回503。 您可以通過設(shè)置spring.cloud.gateway.loadbalancer.use404 = true將網(wǎng)關(guān)配置為返回404。
從LoadBalancer返回的ServiceInstance的isSecure值將覆蓋對網(wǎng)關(guān)的請求中指定的方案。 例如,如果請求通過HTTPS進入網(wǎng)關(guān),但ServiceInstance指示它是不安全的,則下游請求通過HTTP發(fā)出。 相反的情況也可以適用。 但是,如果在網(wǎng)關(guān)配置中為路由指定了GATEWAY_SCHEME_PREFIX_ATTR,則會刪除前綴,并且路由URL產(chǎn)生的方案將覆蓋ServiceInstance配置。
網(wǎng)關(guān)支持所有負(fù)載平衡器功能。您可以在Spring Cloud Commons文檔中關(guān)于它們的內(nèi)容。
6.4、ReactiveLoadBalancerClientFilter
ReactiveLoadBalancerClientFilter在名為ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的交換屬性中查找URI。 如果URL具有l(wèi)b方案(例如lb://myservice),它將使用Spring Cloud ReactorLoadBalancer將名稱(在本示例中為myservice)解析為實際的主機和端口,并替換同一屬性中的URI。 未經(jīng)修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。 篩選器還會在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR屬性中查找其是否等于lb。如果是,則應(yīng)用相同的規(guī)則。 以下清單配置了ReactiveLoadBalancerClientFilter:
spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/**默認(rèn)情況下,當(dāng)ReactorLoadBalancer無法找到服務(wù)實例時,將返回503。 您可以通過設(shè)置spring.cloud.gateway.loadbalancer.use404 = true將網(wǎng)關(guān)配置為返回404。
從ReactiveLoadBalancerClientFilter返回的ServiceInstance的isSecure值將覆蓋對網(wǎng)關(guān)的請求中指定的方案。 例如,如果請求通過HTTPS進入網(wǎng)關(guān),但ServiceInstance指示它是不安全的,則下游請求通過HTTP發(fā)出。 相反的情況也可以適用。 但是,如果在網(wǎng)關(guān)配置中為路由指定了GATEWAY_SCHEME_PREFIX_ATTR,則會刪除前綴,并且路由URL產(chǎn)生的方案將覆蓋ServiceInstance配置。
6.5、The Netty Routing Filter
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中的URL具有http或https方案,則將運行Netty路由篩選器。 它使用Netty HttpClient發(fā)出下游代理請求。 響應(yīng)被放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交換屬性中,以供以后的過濾器使用。 (還有一個實驗性的WebClientHttpRoutingFilter,它執(zhí)行相同的功能,但不需要Netty。)
6.6、The Netty Write Response Filter
如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交換屬性中存在Netty HttpClientResponse,則NettyWriteResponseFilter將運行。 它在所有其他篩選器完成后運行,并將代理響應(yīng)寫回到網(wǎng)關(guān)客戶端響應(yīng)。 (還有一個實驗性的WebClientWriteResponseFilter執(zhí)行相同的功能,但不需要Netty。)
6.7、路由至請求網(wǎng)址過濾器RouteToRequestUrl
如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR交換屬性中有一個Route對象,則RouteToRequestUrlFilter將運行。 它基于請求URI創(chuàng)建一個新URI,但使用Route對象的URI屬性進行更新。 新的URI放置在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中。
如果URI具有方案前綴(例如lb:ws://serviceid),則將從URI中剝離lb方案,并將其放置在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR中,以供稍后在過濾器鏈中使用。
6.8、Websocket路由過濾器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中的URL具有ws或wss方案,則將運行websocket路由篩選器。 它使用Spring WebSocket基礎(chǔ)結(jié)構(gòu)將websocket請求轉(zhuǎn)發(fā)到下游。
您可以通過為URI加上lb前綴來平衡websocket的負(fù)載,例如lb:ws://serviceid。
如果您將SockJS用作常規(guī)HTTP的后備,則應(yīng)配置常規(guī)HTTP路由以及websocket路由。
spring:cloud:gateway:routes:# SockJS route- id: websocket_sockjs_routeuri: http://localhost:3001predicates:- Path=/websocket/info/**# Normal Websocket route- id: websocket_routeuri: ws://localhost:3001predicates:- Path=/websocket/**6.9、網(wǎng)關(guān)指標(biāo)過濾器
要啟用網(wǎng)關(guān)metrics,請?zhí)砑觭pring-boot-starter-actuator作為項目依賴項。 然后,默認(rèn)情況下,只要屬性spring.cloud.gateway.metrics.enabled未設(shè)置為false,網(wǎng)關(guān)度量過濾器就會運行。 該過濾器添加了一個帶有以下標(biāo)記的名為gateway.requests的計時器度量標(biāo)準(zhǔn):
-
routeId:路由ir
-
routeUri:API路由到的URI。
-
outcome:結(jié)果,按HttpStatus.Series分類。
-
status:請求的HTTP狀態(tài)返回給客戶端。
-
httpStatusCode:請求的HTTP狀態(tài)返回給客戶端。
-
httpMethod:用于請求的HTTP方法。
然后,可以從/actuator/metrics/gateway.requests中抓取這些指標(biāo),并且可以輕松地將這些指標(biāo)與Prometheus集成以創(chuàng)建Grafana dashboard。
要啟用prometheus端點,請?zhí)砑觤icrometer-registry-prometheus作為項目依賴項。
6.10、Marking An Exchange As Routed將交換標(biāo)記為路由
網(wǎng)關(guān)路由ServerWebExchange之后,通過將gatewayAlreadyRouted添加到交換屬性,將交換標(biāo)記為“routed”。 將請求標(biāo)記為已路由后,其他路由篩選器將不會再次路由該請求,實質(zhì)上會跳過該篩選器。 您可以使用方便的方法將交換標(biāo)記為已路由,或者檢查交換是否已路由。
-
ServerWebExchangeUtils.isAlreadyRouted接收ServerWebExchange對象,并檢查其是否已“routed”。
-
ServerWebExchangeUtils.setAlreadyRouted接收一個ServerWebExchange對象,并將其標(biāo)記為“routed”。
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud Gateway(一)为什么用网关、能做什么、为什么选择Gateway、谓词工厂、过滤器配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV1.x中的宏定义CV_IS_
- 下一篇: JavaScript 用函数方法比较任意