Spring Cloud Gateway---路由匹配規則


寫在前面 本文參考以下文章,請參考原文

springcloud(十五):服務網關 Spring Cloud GateWay 入門

 Predicate & Spring Cloud Gateway 路由匹配規則

Predicate 來源於 Java 8,是 Java 8 中引入的一個函數,Predicate 接受一個輸入參數,返回一個布爾值結果。該接口包含多種默認方法來將 Predicate 組合成其他復雜的邏輯(比如:與,或,非)。可以用於接口請求參數校驗、判斷新老數據是否有變化需要進行更新操作。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性實現了各種路由匹配規則,有通過 Header、請求參數等不同的條件來進行作為條件匹配到對應的路由。

Spring Cloud Gateway--網關路由 簡單示例了Spring Cloud Gateway的路由功能,現在講一下Spring Cloud Gateway的路由規則。

1.通過時間匹配(datetime)

通過配置predicated 的 Before ,After ,Between 等屬性,可以實現限制路由轉發的時間段。時間對比:Spring 是通過 ZonedDateTime 來對時間進行的對比,ZonedDateTime 是 Java 8 中日期時間功能里,用於表示帶時區的日期與時間信息的類,ZonedDateTime 支持通過時區來設置時間,中國的時區是:Asia/Shanghai

  • Before Route Predicate 剛好相反,在某個時間之前的請求的請求都進行轉發
  • After Route Predicate 是指在這個時間之后的請求都轉發到目標地址
  • Between Route Predicate 只有在這段時間內的請求才進行轉發

Spring Cloud Gateway--網關路由 的例子基礎上修改application.yml如下,就表示在這個時間之前可以進行路由,在這時間之后停止路由,修改完之后重啟項重新啟動網關服務,訪問http://localhost:8080/discoveryClient,頁面會報 404 沒有找到地址

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Before=2020-12-01T06:06:06+08:00[Asia/Shanghai]

修改application.yml如下,就表示在這個時間之后的時間可以進行路由,修改完之后重啟項重新啟動網關服務,訪問http://localhost:8080/discoveryClient,會自動路由到 http://localhost:2001/discoveryClient

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - After=2020-21-01T06:06:06+08:00[Asia/Shanghai]

修改application.yml如下,就表示只有這個時間段內 可以進行路由,修改完之后重啟項重新啟動網關服務,訪問http://localhost:8080/discoveryClient,會自動路由到 http://localhost:2001/discoveryClient

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Between=2020-12-01T06:06:06+08:00[Asia/Shanghai], 2020-12-16T06:06:06+08:00[Asia/Shanghai]

2.通過Cookie匹配(Cookie)

Cookie Route Predicate 可以接收兩個參數,一個是 Cookie name ,一個是正則表達式,路由規則會通過獲取對應的 Cookie name 值和正則表達式去匹配,如果匹配上就會執行路由,如果沒有匹配上則不執行。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Cookie=name, mtest

使用curl命令測試,可以看到帶cookie的請求可以正確路由,正常獲取到頁面返回值,不帶cookie的請求會404

C:\Users\mm>curl http://localhost:8080/discoveryClient --cookie "ityouknow=kee.e"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T03:48:44.034+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"80c9666b-1"}

3.通過 Header 屬性匹配(Header)

Header Route Predicate也是接收 2 個參數,一個 header 中屬性名稱和一個正則表達式,這個屬性值和正則表達式匹配則執行

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Header=X-Request-Id, \d+

使用curl命令測試,可以看到 Header 屬性值和正則表達式匹配的請求可以正確路由,否則會404

C:\Users\mm>curl http://localhost:8080/discoveryClient -H "X-Request-Id:666666"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "X-Request-Id:IO"
{"timestamp":"2020-12-09T07:10:48.753+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"07aaa6b2-2"}

4.通過Host匹配(Host)

Host Route Predicate 接收一組參數,一組匹配的域名列表,這個模板是一個 ant 分隔的模板,用.號作為分隔符。它通過參數中的主機地址作為匹配規則

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Host=**.baidu.com

使用curl命令測試,可以看到  去掉 host 參數或者host參數值和規則不匹配 會報 404 錯誤

C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: cn.baidu.com"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: www.baidu.com"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: www.baid.com"
{"timestamp":"2020-12-09T08:08:35.150+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"3e93a018-4"}
C:\Users\mm>curl http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T08:08:40.223+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"e8d97b0c-5"}

 5.通過請求方式匹配(Method)

可以通過是 POST、GET、PUT、DELETE 等不同的請求方式來進行路由

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Method=GET

curl 分別測試GET , POST 方法,看效果如下。 curl默認是GET方法

C:\Users\mm>curl http://localhost:8080/discoveryClient
Services: []
C:\Users\mm>curl -X POST http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T08:13:14.466+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"3cea7707-2"}

6.通過請求路徑匹配(Path)

Path Route Predicate 接收一個匹配路徑的參數來判斷是否走路由,以上的例子都用了Path匹配

7.通過請求參數匹配(QueryParam)

7.1 Query Route Predicate 支持傳入兩個參數,一個是屬性名一個為屬性值,屬性值可以是正則表達式。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=smile

重啟網關服務,訪問http://localhost:8080/discoveryClient?smile=x, 可以正確路由到 http://localhost:2001/discoveryClient;訪問http://localhost:8080/discoveryClient?smile=x&id=2, 可以正確路由到 http://localhost:2001/discoveryClient;也就是說只要請求中包含 smile 屬性的參數即可匹配路由。

7.2 將 Query 的值以鍵值對的方式進行配置,這樣在請求過來時會對屬性值和正則進行匹配,匹配上才會走路由

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=keep, pu.

重啟網關服務,訪問 http://localhost:8080/discoveryClient?keep=pu2,可以正確路由到 http://localhost:2001/discoveryClient;訪問 http://localhost:8080/discoveryClient?keep=pu23 ,返回404。也就是說:只有當請求中包含 keep 屬性並且參數值是以 pu 開頭的長度為三位的字符串才會進行匹配和路由

7.3 匹配多個請求參數

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=smile
        - Query=keep, pu.

重啟網關服務,訪問 http://localhost:8080/discoveryClient?smile=4&keep=pu8,可以正確路由到 http://localhost:2001/discoveryClient

8.通過請求 ip 地址進行匹配(RemoteAddr)

 Predicate 也支持通過設置某個 ip 區間號段的請求才會路由,RemoteAddr Route Predicate 接受 cidr 符號(IPv4 或 IPv6 )字符串的列表(最小大小為1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子網掩碼)

如果請求的遠程地址是 192.168.1.10,則此路由將匹配。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - RemoteAddr=192.168.1.1/24

可以將此地址設置為本機的 ip 地址進行測試

C:\Users\mm>curl http://localhost:8080/discoveryClient

 9.組合Predicate 

其實以上例子都用了- Path 和 其它Predicate的組合使用。當各種 Predicates 同時存在於同一個路由時,請求必須同時滿足所有的條件才被這個路由匹配。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Before=2020-12-01T06:06:06+08:00[Asia/Shanghai]
        - Cookie=name, mtest
        - Query=smile

10.一個請求滿足多個路由的謂詞條件時,請求只會被首個成功匹配的路由轉發


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM