1. 程式人生 > 程式設計 >Gateway閘道器工作原理及使用方法

Gateway閘道器工作原理及使用方法

目錄
  • 1. 什麼是 API 閘道器(API Gateway)
    • 分散式服務架構、微服務架構與 API 閘道器
    • API 閘道器的定義
    • API 閘道器的職能
    • API 閘道器的分類與功能
  • 2. Gateway是什麼
    • 3. 為什麼用Gateway
      • 最重要的幾個概念
    • 4. Gateway怎麼用
      • 通過時間匹配
      • 通過 Cookie 匹配
      • 通過 Host 匹配
      • 通過請求方式匹配
      • 通過請求路徑匹配
      • 通過請求引數匹配
      • 通過請求 ip 地址進行匹配
      • 組合使用

    1. 什麼是 API 閘道器(API Gateway)

    分散式服務架構、微服務架構與 API 閘道器

    在微服務架構裡,服務的粒度被進一步細分,各個業務服務可以被獨立的設計、開發、測試、部署和管理。這時,各個獨立部署單元可以用不同的開發測試團隊維護,可以使用不同的語言和技術平臺進行設計,這就要求必須使用一種語言和平 臺無關的服務協議作為各個單元間的通訊方式。

    Gateway閘道器工作原理及使用方法

    API 閘道器的定義

    閘道器的角色是作為一個 API 架構,用來保護、增強和控制對於 API 服務的訪問。

    API 閘道器是一個處於應用程式或服務(提供 REST API 介面服務)之前的系統,用來管理授權、訪問控制和流量限制等,這樣 REST API 介面服務就被 API 閘道器保護起來,對所有的呼叫者透明。因此,隱藏在 API 閘道器後面的業務系統就可以專注於建立和管理服務,而不用去處理這些策略性的基礎設施。

    API 閘道器的職能

    Gateway閘道器工作原理及使用方法

    API 閘道器的分類與功能

    Gateway閘道器工作原理及使用方法

    2. Gateway是什麼

    Spring Cloud Gateway是Spring官方基於Spring 5.0,Spring Boot 2.0和Project Reactor等技術開發的閘道器,Spring Cloud Gateway旨在為微服務架構提供一種簡單而有效的統一的API路由管理方式。Spring Cloud Gateway作為Spring Cloud生態系中的閘道器,目標是替代ZUUL,其不僅提供統一的路由方式,並且基於Filter鏈的方式提供了閘道器基本的功能,例如:安全,監控/埋點,和限流等。

    3. 為什麼用Gateway

    Spring Cloud Gateway 可以看做是一個 Zuul 1.x 的升級版和代替品,比 Zuul 2 更早的使用 Netty 實現非同步 IO,從而實現了一個簡單、比 Zuul 1.x 更高效的、與 Spring Cloud 緊密配合的 API 閘道器。

    Spring Cloud Gateway 裡明確的區分了 Router 和 Filter,並且一個很大的特點是內建了非常多的開箱即用功能,並且都可以通過 SpringBoot 配置或者手工編碼鏈式呼叫來使用。

    比如內建了 10 種 Router,使得我們可以直接配置一下就可以隨心所欲的根據 Header、或者 Path、或者 Host、或者 Query 來做MSItrIFi

    路由。

    比如區分了一般的 Filter 和全域性 Filter,內建了 20 種 Filter 和 9 種全域性 Filter,也都可以直接用。當然自定義 Filter 也非常方便。

    最重要的幾個概念

    Gateway閘道器工作原理及使用方法

    Gateway閘道器工作原理及使用方法

    Gateway閘道器工作原理及使用方法

    4. Gateway怎麼用

    說白了 Predicate 就是為了實現一組匹配規則,方便讓請求過來找到對應的 Route 進行處理,接下來我們接下 Spring Cloud GateWay 內建幾種 Predicate 的使用。

    通過時間匹配

    Predicate 支援設定一個時間,在請求進行轉發的時候,可以通過判斷在這個時間之前或者之後進行轉發。比如我們現在設定只有在 2019 年 1 月 1 日才會轉發到我的,在這http://www.cppcns.com之前不進行轉發,我就可以這樣配置:

    spring:
      cloud:
        gateway:
          routes:
           - id: time_route
            uri: http://ityouknow.com
            predicates:
             - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]

    Spring 是通過 ZonedDateTime 來對時間進行的對比,ZonedDateTime 是 8 中日期時間功能裡,用於表示帶時區的日期與時間資訊的類,ZonedDateTime 支援通過時區來設定時間,中國的時區是:Asia/Shanghai

    After Route Predicate 是指在這個時間之後的請求都轉發到目標地址。上面的示例是指,請求時間在 2018 年 1 月 20 日 6 點 6 分 6 秒之後的所有請求都轉發到地址http://ityouknow.com+08:00是指時間和 UTC 時間相差八個小時,時間地區為Asia/Shanghai

    新增完路由規則之後,訪問地址http://localhost:8080會自動轉發到http://ityouknow.com

    Before Route Predicate 剛好相反,在某個時間之前的請求的請求都進行轉發。我們把上面路由規則中的 After 改為 Before,如下:

    spring:
      cloud:
        gateway:
          routes:
           - id: after_route
            uri: http://ityouknow.com
            predicates:
             - Before=2018-01-20T06:06:06+08:00[Asia/Shanghai]

    就表示在這個時間之前可以進行路由,在這時間之後停止路由,修改完之後重啟專案再次訪問地址http://localhost:8080,頁面會報 404 沒有找到地址。

    除過在時間之前或者之後外,Gateway 還支援限制路由請求在某一個時間段範圍內,可以使用 Between Route Predicate 來實現。

    spring:
      cloud:
        gateway:
          routes:
           - id: after_route
            uri: http://ityouknow.com
            predicates:
             - Between=2018-01-20T06:06:06+08:00[Asia/Shanghai],2019-01-20T06:06:06+08:00[Asia/Shanghai]

    這樣設定就意味著在這個時間段內可以匹配到此路由,超過這個時間段範圍則不會進行匹配。通過時間匹配路由的功能很酷,可以用在限時搶購的一些場景中。

    通過 Cookie 匹配

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

    spring:
      cloud:
        gateway:
          routes:
           - id: cookie_route
             uri: http://ityouknow.com
             predicates:
             - Cookie=ityouknow,kee.e

    使用 curl 測試,命令列輸入:

    curl http://localhost:8080 --cookie "ityouknow=kee.e"

    則會返回頁面程式碼,如果去掉--cookie "ityouknow=kee.e",後臺彙報 404 錯誤。

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

    spring:
      cloud:
        gateway:
          routes:
          - id: header_route
            uri: http://ityouknow.com
            predicates:
            - Header=X-Request-Id,\d+

    使用 curl 測試,命令列輸入:

    curl http://localhost:8080  -H "X-Request-Id:666666" 

    則返回頁面程式碼證明匹配成功。將引數-H "X-Request-Id:666666"改為-H "X-Request-Id:neo"再次執行時返回 404 證明沒有匹配。

    通過 Host 匹配

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

    spring:
      cloud:
        gateway:
          routes:
          - id: host_route
            uri: http://ityouknow.com
            predicates:
            - Host=**.ityouknow.com

    使用 curl 測試,命令列輸入:

    curl http://localhost:8080  -H MSItrIFi"Host: www.ityouknow.com" 
    curl http://localhost:8080  -H "Host: md.ityouknow.com" 

    經測試以上兩種 host 均可匹配到 host_route 路由,去掉 host 引數則會報 404 錯誤。

    通過請求方式匹配

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

    spring:
      cloud:
        gateway:
          routes:
          - id: method_route
            uri: http://ityouknow.com
            predicates:
            - Method=GET

    使用 curl 測試,命令列輸入:

    # curl 預設是以 GET 的方式去請求
    curl http://localhost:8080

    測試返回頁面程式碼,證明匹配到路由,我們再以 POST 的方式請求測試。

    # curl 預設是以 GET 的方式去請求
    curl -X POST http://localhost:8080

    返回 404 沒有找到,證明沒有匹配上路由

    通過請求路徑匹配

    Path Route Predicate 接收一個匹配路徑的引數來判斷是否走路由。

    spring:
      cloud:
        gateway:
          routes:
          - id: host_route
            uri: http://ityouknow.com
            predicates:
            - Path=/foo/{segment}

    如果請求路徑符合要求,則此路由將匹配,例如:/foo/1 或者 /foo/bar。

    使用 curl 測試,命令列輸入:

    curl http://localhost:8080/foo/1
    curl http://localhost:8080/foo/xx
    curl http://localhost:8080/boo/xx

    經過測試第一和第二條命令可以正常獲取到頁面返回值,最後一個命令報 404,證明路由是通過指定路由來匹配。

    通過請求引數匹配

    Query Route Predicate 支援傳入兩個引數,一個是屬性名一個為屬性值,屬性值可以是正則表示式。

    spring:
      cloud:
        gateway:
          routes:
          - id: query_route
            uri: http://ityouknow.com
            predicates:
            - Query=smile

    這樣配置,只要請求中包含 smile 屬性的引數即可匹配路由。

    使用 curl 測試,命令列輸入:

    curl localhost:8080?smile=x&id=2

    經過測試發現只要請求彙總帶有 smile 引數即會匹配路由,不帶 smile 引數則不會匹配。

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

    spring:
      cloud:
        gateway:
          routes:
          - id: query_route
            uri: http://ityouknow.com
            predicates:
            - Query=keep,pu.

    這樣只要當請求中包含 keep 屬性並且引數值是以 pu 開頭的長度為三位的字串才會進行匹配和路由。

    使用 curl 測試,命令列輸入:

    curl localhost:8080?keep=pub

    測試可以返回頁面程式碼,將 keep 的屬性值改為 pubx 再次訪問就會報 404,證明路由需要匹配正則表示式才會進行路由。

    通過請求 ip 地址進行匹配

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

    spring:
      cloud:
        gateway:
          routes:
          - id: remoteaddr_route
            uri: http://ityouknow.com
            predicates:
            - RemoteAddr=192.168.1.1/24

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

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

    組合使用

    上面為了演示各個 Predicate 的使用,我們是單個單個進行配置測試,其實可以將各種 Predicate 組合起來一起使用。

    例如:

    spring:
      cloud:
        gateway:
          routes:
           - id: host_foo_path_headers_to_httpbin
            uri: http://ityouknow.com
            predicates:
            - Host=**.foo.org
            - Path=/headers
            - Method=GET
            - Header=X-Request-Id,\d+
            - Query=foo,ba.
            - QueMSItrIFiry=baz
            - Cookie=chocolate,ch.p
            - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]

    各種 Predicates 同時存在於同一個路由時,請求必須同時滿足所有的條件才被這個路由匹配。

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

    到此這篇關於Gateway閘道器工作原理及使用方法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援我們。