在之前的文章的Spring Cloud Gateway初體驗中,大家已經(jīng)對Spring Cloud Gateway的功能有一個初步的認識,網(wǎng)關(guān)作為一個系統(tǒng)的流量的入口,有著舉足輕重的作用,通常的作用如下:
創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、無為網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5技術(shù)、商城系統(tǒng)網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為無為等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。Spring Cloud Gateway作為Spring Cloud框架的第二代網(wǎng)關(guān),在功能上要比Zuul更加的強大,性能也更好。隨著Spring Cloud的版本迭代,Spring Cloud官方有打算棄用Zuul的意思。在筆者調(diào)用了Spring Cloud Gateway的使用和功能上,Spring Cloud Gateway替換掉Zuul的成本上是非常低的,幾乎可以無縫切換。Spring Cloud Gateway幾乎包含了zuul的所有功能。
如上圖所示,客戶端向Spring Cloud Gateway發(fā)出請求。 如果Gateway Handler Mapping確定請求與路由匹配(這個時候就用到predicate),則將其發(fā)送到Gateway web handler處理。 Gateway web handler處理請求時會經(jīng)過一系列的過濾器鏈。 過濾器鏈被虛線劃分的原因是過濾器鏈可以在發(fā)送代理請求之前或之后執(zhí)行過濾邏輯。 先執(zhí)行所有“pre”過濾器邏輯,然后進行代理請求。 在發(fā)出代理請求之后,收到代理服務(wù)的響應(yīng)之后執(zhí)行“post”過濾器邏輯。這跟zuul的處理過程很類似。在執(zhí)行所有“pre”過濾器邏輯時,往往進行了鑒權(quán)、限流、日志輸出等功能,以及請求頭的更改、協(xié)議的轉(zhuǎn)換;轉(zhuǎn)發(fā)之后收到響應(yīng)之后,會執(zhí)行所有“post”過濾器的邏輯,在這里可以響應(yīng)數(shù)據(jù)進行了修改,比如響應(yīng)頭、協(xié)議的轉(zhuǎn)換等。
在上面的處理過程中,有一個重要的點就是講請求和路由進行匹配,這時候就需要用到predicate,它是決定了一個請求走哪一個路由。
Predicate 來源于 Java 8,是 Java 8 中引入的一個函數(shù),Predicate 接受一個輸入?yún)?shù),返回一個布爾值結(jié)果。該接口包含多種默認方法來將 Predicate 組合成其他復(fù)雜的邏輯(比如:與,或,非)??梢杂糜诮涌谡埱髤?shù)校驗、判斷新老數(shù)據(jù)是否有變化需要進行更新操作。
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性實現(xiàn)了各種路由匹配規(guī)則,有通過 Header、請求參數(shù)等不同的條件來進行作為條件匹配到對應(yīng)的路由。網(wǎng)上有一張圖總結(jié)了 Spring Cloud 內(nèi)置的幾種 Predicate 的實現(xiàn)。
說白了 Predicate 就是為了實現(xiàn)一組匹配規(guī)則,方便讓請求過來找到對應(yīng)的 Route 進行處理,接下來我們接下 Spring Cloud GateWay 內(nèi)置幾種 Predicate 的使用。
Predicate 支持設(shè)置一個時間,在請求進行轉(zhuǎn)發(fā)的時候,可以通過判斷在這個時間之前或者之后進行轉(zhuǎn)發(fā)。比如我們現(xiàn)在設(shè)置只有在2019年2月15日才會轉(zhuǎn)發(fā)到我的簡書地址,在這之前不進行轉(zhuǎn)發(fā),我就可以這樣配置:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://httpbin.org
predicates:
- After=2018-02-15T00:00:00+08:00[Asia/Shanghai]
Spring 是通過 ZonedDateTime 來對時間進行的對比,ZonedDateTime 是 Java 8 中日期時間功能里,用于表示帶時區(qū)的日期與時間信息的類,ZonedDateTime 支持通過時區(qū)來設(shè)置時間,中國的時區(qū)是:Asia/Shanghai。
After Route Predicate 是指在這個時間之后的請求都轉(zhuǎn)發(fā)到目標(biāo)地址。上面的示例是指,請求時間在 2019年2月15日0點0分0秒之后的所有請求都轉(zhuǎn)發(fā)到地址http://httpbin.org。+08:00是指時間和UTC時間相差八個小時,時間地區(qū)為Asia/Shanghai
添加完路由規(guī)則之后,訪問地址 http://127.0.0.1:8080/get 會自動轉(zhuǎn)發(fā)到 http://httpbin.org/get
Before Route Predicate 剛好相反,在某個時間之前的請求的請求都進行轉(zhuǎn)發(fā)。我們把上面路由規(guī)則中的 After 改為 Before,如下:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://httpbin.org
predicates:
- Before=2019-02-15T00:00:00+08:00[Asia/Shanghai]
就表示在2019-02-14之前可以進行路由,在這時間之后停止路由,修改完之后重啟項目再次訪問地址http://localhost:8080,頁面會報 404 沒有找到地址。
除過在時間之前或者之后外,Gateway 還支持限制路由請求在某一個時間段范圍內(nèi),可以使用 Between Route Predicate 來實現(xiàn)。
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://httpbin.org
predicates:
- Between=2018-02-14T00:00:00+08:00[Asia/Shanghai], 2019-02-16T23:59:59+08:00[Asia/Shanghai]
這樣設(shè)置就意味著在 2019-02-14到2019-02-16 時間段內(nèi)可以匹配到此路由,超過這個時間段范圍則不會進行匹配。通過時間匹配路由的功能很酷,可以用在限時搶購的一些場景中。
Cookie Route Predicate 可以接收兩個參數(shù),一個是 Cookie name ,一個是正則表達式,路由規(guī)則會通過獲取對應(yīng)的 Cookie name 值和正則表達式去匹配,如果匹配上就會執(zhí)行路由,如果沒有匹配上則不執(zhí)行。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://httpbin.org:80
predicates:
- Cookie=name, chengxuyuanguoguo
上面的配置中,請求帶有cookie名為name, cookie值為chengxuyuanguoguo 的請求將都會轉(zhuǎn)發(fā)到uri為 http://httpbin.org的地址上。
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080/get --cookie "name=chengxuyuanguoguo"
則有正確返回,如果去掉--cookie "name=chengxuyuanguoguo",沒有匹配成功,出現(xiàn) 404 錯誤。
Header Route Predicate 和 Cookie Route Predicate 一樣,也是接收 2 個參數(shù),一個 header 中屬性名稱和一個正則表達式,這個屬性值和正則表達式匹配則執(zhí)行。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://httpbin.org
predicates:
- Header=X-Request-Id, \d+
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080/get -H "X-Request-Id:111111"
則正常返回,將參數(shù) "X-Request-Id:111111" 改為 "X-Request-Id:xxxx" 再次執(zhí)行時返回404。
Host Route Predicate 接收一組參數(shù),一組匹配的域名列表,這個模板是一個 ant 分隔的模板,用.號作為分隔符。它通過參數(shù)中的主機地址作為匹配規(guī)則。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://ityouknow.com
predicates:
- Host=**.ityouknow.com
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080/get -H "Host:www.httpbin.com"
測試上述 host 可匹配到 host_route 路由,去掉 host 參數(shù)則會報 404 錯誤。
可以通過是 POST、GET、PUT、DELETE 等不同的請求方式來進行路由。
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://httpbin.org
predicates:
- Method=GET
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080/get
測試返回正確,證明匹配到路由,再以 POST 的方式請求測試:
curl -X POST http://127.0.0.1:8080/get
返回 404 沒有找到,沒有匹配上路由。
Path Route Predicate 接收一個匹配路徑的參數(shù)來判斷是否走路由。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://httpbin.org
predicates:
- Path=/foo/{segment}
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080/foo/1
curl http://127.0.0.1:8080/fee/1
測試第一命令可以正常獲取到頁面返回值,第二個命令報404,證明路由是通過指定路由來匹配。
Query Route Predicate 支持傳入兩個參數(shù),一個是屬性名一個為屬性值,屬性值可以是正則表達式。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://httpbin.org
predicates:
- Query=foo
測試發(fā)現(xiàn)只要請求帶有 foo 參數(shù)即會匹配路由,不帶 foo 參數(shù)則會報 404 錯誤。
Predicate 也支持通過設(shè)置某個 ip 區(qū)間號段的請求才會路由,RemoteAddr Route Predicate 接受 cidr 符號(IPv4 或 IPv6 )字符串的列表(最小大小 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子網(wǎng)掩碼)。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://httpbin.org
predicates:
- RemoteAddr=172.16.1.73/24
使用 curl 測試,命令行輸入:
curl http://172.17.1.73:8080/get
測試返回正確,改為請求 127.0.0.1:8080/get 則會報 404 錯誤。
Predicate還可以組合在一起使用。
spring:
cloud:
gateway:
routes:
- id: group_route
uri: http://httpbin.org
predicates:
- Host=**.httpbin.com
- Header=X-Request-Id, \d+
- Cookie=name, chengxuyuanguoguo
- After=2019-02-15T00:00:00+08:00[Asia/Shanghai]
使用 curl 測試,命令行輸入:
curl http://127.0.0.1:8080 -H "X-Request-Id:111111" -H "Host:www.httpbin.com" --cookie "name=chengxuyuanguoguo"
測試返回正確,錯誤的規(guī)則或去除一個規(guī)則,則會報 404 錯誤。
Predict作為斷言,它決定了請求會被路由到哪個router 中。在斷言之后,請求會被進入到filter過濾器的邏輯,下篇文章將會介紹Spring Cloud Gateway過濾器相關(guān)的內(nèi)容。
源碼:https://github.com/gf-huanchupk/SpringCloudLearning/tree/master/chapter13/springcloud-gateway-predict
歡迎關(guān)注我的公眾號《程序員果果》,關(guān)注有驚喜~~
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。