文章目錄
- 核心概念
- 1 斷言
-
- (1)AfterRoutePredicateFactory
- (2)BeforeRoutePredicateFactory
- (3)BetweenRoutePredicateFactory
- (4)MethodRoutePredicateFactory
- (5)CookieRoutePredicateFactory
- (6)HostRoutePredicateFactory
- (7)HeaderRoutePredicateFactory
- (8)PathRoutePredicateFactory
- (9)WeightRoutePredicateFactory
- (10)RemoteAddrRoutePredicateFactory
- (11)QueryRoutePredicateFactory
- (12)CloudFoundryRouteServiceRoutePredicateFactory
- (13)組合斷言
- 2 過濾器
-
- 2.1 網關過濾器
- 2.2 全局過濾器
- 3 過濾器的順序
- 參考文章
核心概念
- 路由(Route):路由是網關的基本構件。它由ID、目标URI、一組斷言和一組過濾器組成。如果斷言為真,則比對該路由。gateway使用類RouteDefinition表示路由定義。
- 斷言(Predicate):參照Java8的新特性Predicate。Predicate接受一個輸入參數,傳回一個布爾值結果,輸入參數可以是HTTP請求的任何部分,比如封包頭、參數、封包體,而且還可以将多個斷言組合在一起。
- 過濾器(Filter):可以在發送到目标URI之前或之後修改請求和響應。
1 斷言
spring cloud gateway 2.2.9.RELEASE版本裡面,提供了12個斷言,gateway使用工廠模式建立這些斷言,它們都是在斷言工廠裡面建立的。這些斷言工廠都繼承了抽象類AfterRoutePredicateFactory。下面分别介紹這些斷言的作用和例子。
(1)AfterRoutePredicateFactory
該斷言支援設定一個時間,轉發請求時,如果在該時間之後,則斷言為真。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- After=2021-09-10T00:00:00+08:00
這個斷言會在東8區的2021-09-10 淩晨12點之後,将請求都轉跳到http://localhost:8079。
(2)BeforeRoutePredicateFactory
與AfterRoutePredicateFactory相反,BeforeRoutePredicateFactory表示在指定的時間之前的請求都進行跳轉。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Before=2021-09-10T00:00:00+08:00
這個斷言會在東8區的2021-09-10 淩晨12點之前,将請求都轉跳到http://localhost:8079。
(3)BetweenRoutePredicateFactory
BetweenRoutePredicateFactory接受兩個時間,它表示轉發在指定時間之間的請求。比如:
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Between=2021-09-01T10:00:00+08:00,2021-09-10T12:00:00+08:00 # 比對兩個時間之間
(4)MethodRoutePredicateFactory
MethodRoutePredicateFactory根據POST、GET、PUT、DELETE 等不同的HTTP方法進行判斷。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Method=GET
上面例子中,所有的GET請求都會被轉發。Method可以指定多個。
(5)CookieRoutePredicateFactory
CookieRoutePredicateFactory根據cookie内容進行判斷。它有兩個參數,一個是cookie名,另一個是value,value使用正規表達式,當cookie中含有指定的cookie名,且值符合value的正規表達式,則将轉發請求。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Cookie=sessionId, test
當cookie中含有sessionId=test的内容時,轉發請求。
(6)HostRoutePredicateFactory
HostRoutePredicateFactory使用一組主機清單作為判斷條件。如果目前請求的封包頭中含有屬性“Host”,且其值在指定的主機清單裡面,則将轉發請求。主機清單使用Ant style比對。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Host=**.maven.org,**.spring.org
(7)HeaderRoutePredicateFactory
HeaderRoutePredicateFactory指定了兩個參數,一個header的name,一個是正則比對的value。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Header=X-Request-Id, \d+
上述規則比對header中存在名為X-Request-Id,内容為數字的請求。
(8)PathRoutePredicateFactory
PathRoutePredicateFactory使用Spring的PathPattern比對請求path。PathPattern支援多種規則,可以使用類似Ant style,也可以使用正規表達式,具體的規則在PathPattern類中有詳細說明。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Path=/demo/**
上述規則比對所有以/demo/開頭的路徑。
(9)WeightRoutePredicateFactory
WeightRoutePredicateFactory基于權重進行路由,配置時指定分組和權重值。下面網頁對于配置規則及算法進行了詳細說明:
https://www.cnblogs.com/liukaifeng/p/10055866.html
(10)RemoteAddrRoutePredicateFactory
RemoteAddrRoutePredicateFactory可以指定被請求的遠端位址,當位址符合要求時,請求才會轉發。可以在位址裡面指定子網路遮罩。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- RemoteAddr=192.168.1.1/24
上述例子中,子網路遮罩是24,凡是請求的遠端位址為192.168.1.XXX都會被轉發。
(11)QueryRoutePredicateFactory
QueryRoutePredicateFactory入參也是兩個參數,一個是請求參數的屬性名,另一個是屬性值,屬性值使用正規表達式。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Query=role,ba.
(12)CloudFoundryRouteServiceRoutePredicateFactory
CloudFoundryRouteServiceRoutePredicateFactory在雲計算場景下使用。它判斷header裡面是否有屬性:X-CF-Forwarded-Url、X-CF-Proxy-Signature和X-CF-Proxy-Metadata。當header裡面同時有上述三個屬性時,請求才會被轉發。
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- CloudFoundry=XXX
CloudFoundry的值對請求轉發不起作用,可以随意寫任何值。
(13)組合斷言
我們可以組合上面介紹的斷言一起使用。比如:
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Path=/demo/**
- Query=role,ba.
- After=2021-09-10T00:00:00+08:00
當所有的斷言都為真時,請求才會被轉發。
2 過濾器
過濾器可以修改HTTP請求的輸入和輸出,Spring Cloud Gateway内置了很多不同功能的過濾器。在gateway中,過濾器有兩個頂級接口,這也将過濾器分為兩類:
- GatewayFilter:網關過濾器,需要通過
配置在具體路由下,隻作用在目前路由上或通過spring.cloud.routes.filters
配置在全局,作用在所有路由上。spring.cloud.default-filters
- GlobalFilter:全局過濾器,不需要在配置檔案中配置,作用在所有的路由上,最終通過
包裝成GatewayFilterAdapter
可識别的過濾器。GatewayFilterChain
gateway提供了很多過濾器,本文隻介紹部分過濾器介紹。網關過濾器使用了工廠模式,均是由對應的工廠類建立,工廠類都實作自GatewayFilterFactory接口。
2.1 網關過濾器
(1)AddRequestHeaderGatewayFilterFactory
AddRequestHeaderGatewayFilterFactory可以在header裡面增加指定的name和value。比如:
spring:
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
filters:
- AddRequestHeader=X-Request,BAR
對被轉發的請求,會在header裡面額外添加屬性值X-Request=Bar。
(2)AddResponseHeaderGatewayFilterFactory
AddResponseHeaderGatewayFilterFactory在請求響應的header裡面添加指定的name和value。比如:
spring:
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
filters:
- AddResponseHeader=X-Request,BAR
當收到響應後,在header裡面增加屬性值X-Request=Bar。
(3)RemoveRequestHeaderGatewayFilterFactory
RemoveRequestHeaderGatewayFilterFactory在header裡面删除指定的name。
(4)MapRequestHeaderGatewayFilterFactory
MapRequestHeaderGatewayFilterFactory指定兩個header的屬性名:fromHeader和toHeader,轉發請求前,過濾器将屬性名從fromHeader替換為toHeader,屬性值不變。
(5)RewritePathGatewayFilterFactory
RewritePathGatewayFilterFactory可以對請求路徑重寫。過濾器指定兩個參數:regexp和replacement,兩個參數都使用正規表達式,前者指定要替換的内容,後者表示被替換後的内容。
spring:
cloud:
gateway:
routes:
- id: route-demo
uri: http://localhost:8079
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
對于上面的例子,如果請求的路徑是/foo/bar,則gateway會将請求路徑改為/bar發送給下遊。
(6)PrefixPathGatewayFilterFactory
該過濾器工廠為比對的URI添加指定字首。
(7)AddRequestParameter
該過濾器将指定參數添加請求中。
還有其他過濾器,本文不再介紹。請參見文章:
https://blog.csdn.net/abu935009066/article/details/112252692
2.2 全局過濾器
全局過濾器實作了Order接口,該接口的作用用于指定過濾器的順序,數字越小,優先級越高。
(1)NettyWriteResponseFilter
使用Netty與請求方建立的連接配接将收到的代理響應寫回請求端。
(2)GatewayMetricsFilter
該過濾器用于監控,提供監控名額。它統計請求成功、失敗的次數,請求耗時時長等。
該過濾器需要依賴spring-boot-starter-actuator。
(3)NoLoadBalancerClientFilter
該過濾器要求目标URI的schema不能是“
lb
”,否則向請求方傳回404。
lb表示從注冊中心擷取目标URL。
如果要使該過濾器失效,則需要引入Ribbon。
(4)WebClientWriteResponseFilter
使用WebClient與請求方建立的連接配接将收到的代理響應寫回請求端。
(5)WebClientHttpRoutingFilter
使用WebClient向目标URI發送
http
和
https
請求。不過在發送前,要先經過gateway中的其他過濾器處理,在所有的過濾器都處理完畢後,再發送請求。
(6)ForwardRoutingFilter
ForwardRoutingFilter會檢視用戶端請求的URI的schema是否是
forward
,比如:forward://localendpoint,如果是,則它會使用Spring的
DispatcherHandler
來處理這個請求。
(7)ForwardPathFilter
ForwardPathFilter會檢視目标URI的scheme是否是
forward
,比如:
forward://localendpoint
,如果是,則它會使用Spring的
DispatcherHandler
來處理這個請求。
(8)RouteToRequestUrlFilter
這個過濾器用于将從request裡擷取的原始URL轉換成Gateway轉發時所使用的URL。
如果 URL 具有 scheme 字首,例如
lb:ws://serviceid
,該 lb scheme将從URL中剝離,并放到Gateway上下文中,友善後面的過濾器使用。
(9)ReactiveLoadBalancerClientFilter
該過濾器依賴
spring-cloud-starter-loadbalancer
。
如果原始URL或者目标URL的scheme為“
lb
”,比如:
lb://myservice
,那麼ReactiveLoadBalancerClientFilter使用ReactorLoadBalancer查找myservice的服務位址清單,并且使用負載均衡算法選擇合适的位址。
(10)NettyRoutingFilter
使用Netty的
HttpClient
向目标URI發送
http
和
https
請求。不過在發送前,要先經過gateway中的其他過濾器處理,在所有的過濾器都處理完畢後,再發送請求。
(11)WebsocketRoutingFilter
使用WebSocketService向目标URI發送
ws
和
wss
請求。
3 過濾器的順序
當請求到來時,gateway添加所有GlobalFilter執行個體和比對的GatewayFilter執行個體到過濾器鍊中,通過對filter bean配置注解
@Order
,過濾器鍊會對這些過濾器執行個體進行排序。
Spring Cloud Gateway将過濾器的邏輯按請求執行點分為”
pre
”和”
post
”的一前一後處理,如果是高優先級的過濾器,則在”
pre
”邏輯中最先執行,在”
post
”邏輯中最後執行。
參考文章
https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html