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