1. 程式人生 > >Spring Cloud之Gateway(一):基本瞭解及謂詞詳解

Spring Cloud之Gateway(一):基本瞭解及謂詞詳解

版本:2.0.2.RELEASE

連結:http://spring.io/projects/spring-cloud-gateway#overview

本章主要目錄如下

Spring Cloud Gateway是什麼?

Spring Cloud Gateway特徵有什麼?

Spring Cloud Gateway應如何引入?

Spring Cloud Gateway詞彙表有什麼?

Spring Cloud Gateway如何工作?

Spring Cloud Gateway謂詞是什麼?

 

本章主要內容如下

1.Spring Cloud Gateway是什麼

該專案提供了一個用於在Spring MVC之上構建API閘道器的庫。Spring Cloud Gateway旨在提供一種簡單而有效的方式來路由到API,併為他們提供橫切關注點,例如:安全性,監控/指標和彈性。

 

2.Spring Cloud Gateway特徵有什麼

  • 基於Spring Framework 5,Project Reactor和Spring Boot 2.0構建

  • 能夠匹配任何請求屬性上的路由。

  • 謂詞和過濾器對於路由是特定的。

  • Hystrix斷路器整合。

  • Spring Cloud DiscoveryClient整合

  • 易於編寫謂詞和過濾器

  • 請求率限制

  • 路徑重寫

 

3.Spring Cloud Gateway應如何引入

要在專案中引入 Spring Cloud Gateway,請使用 org.springframework.cloud 啟動依賴包,其構件id是spring-cloud-starter-gateway。請參閱Spring Cloud Project頁面,以獲取有關使用當前 Spring Cloud Release Train 設定構建系統的詳細資訊。如果引入啟動依賴包,但由於某種原因,您不希望啟用閘道器,請設定 spring.cloud.gateway.enabled =false。

Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供 Netty 執行時。它不能在傳統的 Servlet 容器中工作或構建為 WAR。

 

4.Spring Cloud Gateway詞彙表有什麼?

路由:路由是閘道器的基本構建模組。它由一個 ID,一個目標 URI,一組謂詞和一個過濾器的集合定義。如果聚合謂詞為真,則路由匹配。

謂詞:這是一個 Java 8 函式謂詞。輸入型別是一個 Spring 框架的 ServerWebExchange。這允許開發人員匹配來自 HTTP 請求的任何內容,例如頭部或引數。

過濾器:這些是 Spring 框架閘道器過濾器在特定工廠中構建的例項。這裡,可以在傳送下游請求之前或之後修改請求和響應。

 

5.Spring Cloud Gateway如何工作?

客戶端向 Spring Cloud Gateway 發出請求。如果閘道器處理程式對映確定請求與路由匹配,則將其傳送到閘道器 Web 處理程式。這個執行的處理程式通過特定於請求的過濾器鏈傳送請求。過濾器被虛線劃分的原因是過濾器可以在傳送代理請求之前或之後執行邏輯。執行所有“pre”過濾器邏輯,然後進行代理請求。在發出代理請求之後,執行“post”過濾器邏輯。

注意:在沒有埠的路由中定義的URI將分別為HTTP和HTTPS URI獲取預設埠設定為80和443。

6.Spring Cloud Gateway謂詞是什麼?

Spring Cloud Gateway 將路由作為 Spring WebFlux HandlerMapping 基礎結構的一部分進行匹配。Spring Cloud Gateway 包含許多內建的路由謂詞工廠。所有這些謂詞都匹配 HTTP 請求的不同屬性。多個謂詞工廠可以通過邏輯與進行組合。

  • After 路由謂詞工廠

After 路由謂詞工廠採用一個 datetime 型別的引數。此謂詞匹配當前日期時間之後發生的請求。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: after_route

        uri: http://example.org

        predicates:

        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

此路由與 2017 年 1 月 20 日 17:42 MountainTime(Denver)之後的所有請求相匹配。

 

  • Before 路由謂詞工廠

Before 路由謂詞工廠採用一個 datetime 型別的引數。此謂詞匹配當前日期時間之前發生的請求。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: before_route

        uri: http://example.org

        predicates:

        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

此路由與 2017 年 1 月 20 日 17:42 MountainTime(Denver)之後的所有請求相匹配。

 

  • Between 路由謂詞工廠

Between 路由謂詞工廠採用兩個引數,datetime1 和datetime2。此謂詞匹配datetime1 之後和 datetime2 之前發生的請求。datetime2 引數必須在 datetime1 之後。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: between_route

        uri: http://example.org

        predicates:

        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

 

此路由與 2017 年 1 月 20 日 17:42 Mountain Time (Denver)之後和 2017 年 1 月 21 日17:42 Mountain Time (Denver)之前的所有請求相匹配,這對維護視窗很有用。

 

  • Cookie 路由謂詞工廠

Cookie 路由謂詞工廠採用兩個引數,cookie 名稱和正則表示式。此謂詞匹配具有給定名稱的 cookie,值與正則表示式匹配。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: cookie_route

        uri: http://example.org

        predicates:

        - Cookie=chocolate, ch.p

此路由與請求匹配的 cookie 名稱為 chocolate,其值與 CH.P 正則表示式匹配。

 

  • Header 路由謂詞工廠

Header 路由謂詞工廠採用兩個引數,Header 名稱和正則表示式。此謂詞與具有給定名稱且值與正則表示式匹配的 Header 匹配。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: header_route

        uri: http://example.org

        predicates:

        - Header=X-Request-Id, \d+

如果請求具有名為 X-Request-Id 的 Header,其值與\d+正則表示式匹配(具有一個或多個數字的值),則該路由匹配。

 

  • Host 路由謂詞工廠

Host 路由謂詞工廠採用一個引數:主機名模式。該模式是一種 Ant 樣式模式作為分隔符。此謂詞與匹配該模式的主機頭部匹配。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: host_route

        uri: http://example.org

        predicates:

        - Host=**.somehost.org

如果請求的主機頭部具有值www.somehost.org或beta.somehost.org,則此路由將匹配。

 

  • Method 路由謂詞工廠

Method 路由謂詞工廠採用一個引數:要匹配的 HTTP 方法。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: method_route

        uri: http://example.org

        predicates:

        - Method=GET

如果請求方法是 GET,則此路由將匹配。

 

  • Path 路由謂詞工廠

Path 路由謂詞工廠採用一個引數:Spring PurthMatter 模式。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: host_route

        uri: http://example.org

        predicates:

        - Path=/foo/{segment}

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

此謂詞提取 URI 模板變數(如上面示例中定義的 segment)作為名稱和值的對映,並將其放置在 ServerWebExchange.getAttributes()中,其中鍵定義在

PathRoutePre.e.URL_PREDICATE_VARS_ATTR 中。這些值隨後可供閘道器過濾器工廠使用。

 

  • Query 路由謂詞工廠

Query 路由謂詞工廠採用兩個引數:一個必需的引數和一個可選的正則表示式。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: query_route

        uri: http://example.org

        predicates:

        - Query=baz

如果請求包含 baz 查詢引數,此路由將匹配。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: query_route

        uri: http://example.org

        predicates:

        - Query=foo, ba.

如果請求包含一個 foo 查詢引數,它的值與 ba.正則表示式匹配,則此路由將匹配,所以bar 和 baz 都將匹配。

 

  • RemoteAddr 路由謂詞工廠

RemoteAddr 路由謂詞工廠採用 CIDR 符號(IPv4 或 IPv6)字串的列表(最小值為1),例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子網掩碼)。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: remoteaddr_route

        uri: http://example.org

        predicates:

        - RemoteAddr=192.168.1.1/24

如果請求的遠端地址為192.1681.10,則該路由將匹配。

 

  • 修改遠端地址的解析方式

預設情況下,RemoteAddr 路由謂詞工廠使用傳入請求中的遠端地址。如果 Spring Cloud Gateway 位於代理層後面,則可能與實際客戶端 IP 地址不匹配。可以通過設定自定義RemoteAddressResolver來自定義解析遠端地址的方式。Spring Cloud Gateway 附帶一個非預設遠端地址解析器,它基於 X-Forwarded-For 頭部和XForwardedRemoteAddressResolver。

XForwardedRemoteAddressResolver 有兩種靜態建構函式方法,它們採用不同的安全方法:

XForwardedRemoteAddressResolver::trustAll 返回一個 RemoteAddressResolver,它總是使用在 X-Forwared-For 報頭中找到的第一個 IP 地址。這種方法容易受到欺騙,因為惡意客戶端可以為解析器接收的 X-Forwared-For 設定初始值。

XForwardedRemoteAddressResolver :: maxTrustedIndex 採用與 Spring Cloud Gateway 前面執行的可信基礎設施數量相關的索引。例如,如果只能通過 HAProxy 訪問 Spring Cloud Gateway,則應使用值 1。如果在訪問 Spring Cloud Gateway 之前需要兩跳可信基礎設施,那麼應該使用值 2。

 

給出以下頭部值:

 

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

 

下面的 maxTrustedIndex 值將產生以下遠端地址。

 

使用 Java 配置:

GatewayConfig.java

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver

    .maxTrustedIndex(1);

...

.route("direct-route",

    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")

        .uri("https://downstream1")

.route("proxied-route",

    r -> r.remoteAddr(resolver,  "10.10.1.1", "10.10.1.1/24")

        .uri("https://downstream2")

)

 

關注米兜Java,下一章將一起討論閘道器過濾器工廠。