Spring Cloud Gateway 4.0 中的有趣新過濾器

工程 | Marta Medio | 2023 年 1 月 18 日 | ...

Spring Cloud Gateway 4.0 終於來了!感謝社群貢獻,我們引入了新特性和有趣的過濾器。

這篇博文詳細介紹了新亮點,並解釋了其中一些新過濾器的工作原理以及如何使用它們來更深入地瞭解您的應用程式。

首先,我們來談談快取!快取是一個複雜的問題,正因如此,我們引入了兩個與其相關的新過濾器,但請注意,這些過濾器可能會限制閘道器的記憶體,因此請謹慎使用。

CacheRequestBody

如果處理不當,操作請求體可能會導致問題,所以我們為您簡化了操作;透過這個過濾器,我們可以在請求體傳送到下游之前對其進行快取,並透過交換屬性獲取該請求體。它將儲存在 ServerWebExchange.getAttributes() 中,鍵名由 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定義,以便在後續過濾器中使用。

配置該過濾器,只需簡單指定要轉換成的請求體類型別即可。

spring:
  cloud:
    gateway:
      routes:
      - id: cache_request_body_route
        uri: http://downstream
        predicates:
        - Path=/get/**
        filters:
        - name: CacheRequestBody
          args:
            bodyClass: java.lang.String

此過濾器僅適用於 HTTP 請求(包括 HTTPS)。

LocalCacheResponseBody

有時您的閘道器會呼叫一些服務,您知道它們的響應隨時間不會發生變化。為了提高效能並避免每次請求都去下游獲取相同的響應,我們添加了一個新過濾器,允許對響應體和響應頭進行本地快取。

此新功能在全域性級別實現,但也可在路由級別覆蓋全域性配置,為那些您知道需要特殊處理的路由設定特定行為。

有一些條件必須考慮在內

  • 它只快取沒有請求體的 GET 請求。
  • 它只快取狀態碼為以下值的響應:HTTP 200 (OK), HTTP 206 (Partial Content) 和 HTTP 301 (Moved Permanently)。
  • 我們遵循 HTTP Cache-Control 規範,因此只有在 Cache-Control 頭部允許的情況下才會進行快取。這意味著請求中沒有 no-store,響應中沒有 no-storeprivate。此外,如果響應已快取,並且新的請求在 Cache-Control 頭部帶有 no-cache 值,則將返回一個無響應體且狀態碼為 HTTP 304 (Not Modified) 的響應。

要啟用此全域性快取過濾器,只需將以下屬性設定為 true 即可:spring.cloud.gateway.filter.local-response-cache.enabled

我們提供了一些配置屬性來管理響應快取的工作方式,透過 spring.cloud.gateway.filter.local-response-cache.size,您可以設定快取的最大大小以驅逐條目,它接受 KBMBGB 的大小格式;spring.cloud.gateway.filter.local-response-cache.timeToLive 屬性設定快取條目的過期時間,以 s 表示秒,m 表示分鐘,h 表示小時。

spring:
  cloud:
    gateway:
      filter:
	  local-response-cache:
	    enabled: true
	    timeToLive: 20m
	    size: 6MB

如果未配置這些引數中的任何一個,但用於啟用全域性過濾器的屬性已啟用,則閘道器預設將快取響應的生存時間配置為 5 分鐘,且無大小限制。

如前所述,我們提供了在每個路由上實現過濾器來覆蓋全域性配置的可能性。但請注意,必須啟用全域性過濾器才能設定每個路由的配置!路由配置接受第一個引數來覆蓋該路由驅逐條目的最大快取大小(大小格式為 KBMBGB),以及第二個引數來覆蓋快取條目的過期時間(以 s 表示秒,m 表示分鐘,h 表示小時)

spring:
 cloud:
   gateway:
     routes:
     - id: local_response_cache_get_route
       uri: http://downstream
       predicates:
       - Path=/get/data
       filters:
       - LocalResponseCache=10s,10MB

此功能背後的一個有趣之處在於,它還實現了 HTTP Cache-Control 頭部中 max-age 值的計算。因此,如果原始響應中存在 max-age,則該值將使用 timeToLive 配置引數中設定的秒數進行重寫,在後續呼叫中,此值將根據響應過期前剩餘的秒數重新計算。

AddRequestHeadersIfNotPresent

過濾器的名稱幾乎說明了一切,它與 AddRequestHeader 的工作方式非常相似,但與 AddRequestHeader 不同的是,它只在請求中不存在該頭部時才新增。否則,將傳送客戶端請求中的原始值。

它接受由冒號分隔的名稱-值對集合

spring:
 cloud:
   gateway:
     routes:
     - id: add_request_header_route
       uri: http://downstream
       predicates:
       - Path=/colors
       filters:
       - AddRequestHeadersIfNotPresent=X-Request-Color:blue,X-Header-Color:red

它還支援用於匹配路徑或主機的 URI 變數

spring:
 cloud:
   gateway:
     routes:
     - id: add_request_header_route
       uri: http://downstream
       predicates:
       - Path=/colors/{segment}
       filters:
       - AddRequestHeadersIfNotPresent=X-Request-Red:blue-{segment}

您還可以設定一個多值頭部!只需多次新增相同的頭部名稱/值即可。

spring:
 cloud:
   gateway:
     routes:
     - id: add_request_header_route
       uri: http://downstream
       predicates:
       - Path=/colors/
       filters:
       - AddRequestHeadersIfNotPresent=X-Request-Color:blue,X-Request-Color:green

RemoveJsonAttributesResponseBody

JSON 是最常用的資料表示格式之一,正因如此,我們希望新增更多針對此格式響應的特定功能。此過濾器提供了一種方便的方法,透過刪除 JSON 體內容中的屬性來應用轉換。

它接受要查詢的屬性名稱集合,列表中的最後一個引數可以是可選的布林值,用於僅在根級別刪除屬性(這是預設值 false,如果引數配置末尾沒有提供)或遞迴刪除屬性(true)。

spring:
 cloud:
   gateway:
     routes:
     - id: remove_json_attributes_route
       uri: https://downstream
 	 predicates:
       - Path=/json/
       filters:
       - RemoveJsonAttributesResponseBody=created_date,color

上述配置將從 JSON 內容體中移除屬性,但僅限於根級別。

spring:
 cloud:
   gateway:
     routes:
     - id: remove_json_attributes_route
       uri: https://downstream
 	 predicates:
       - Path=/json/
       filters:
       - RemoveJsonAttributesResponseBody=created_date,color,true

在末尾新增 true 屬性將移除 JSON 結構中任何級別的屬性。

這些過濾器增加了強大的新功能。我們很想聽聽它們如何支援您的用例以及我們如何提高您的工作效率。您可以在其參考文件中找到有關此新過濾器和其他功能的更多資訊。

感謝所有透過報告和拉取請求做出貢獻的人們!

額外資源

想了解更多關於 Spring Cloud 的資訊嗎?歡迎線上加入我們的 SpringOne 大會!想了解更多關於 Spring Cloud Gateway 的功能嗎?請檢視我們支援 Kubernetes 的商業平臺

訂閱 Spring 郵件列表

透過 Spring 郵件列表保持聯絡

訂閱

搶佔先機

VMware 提供培訓和認證,助力您加速前行。

瞭解更多

獲取支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一個簡單的訂閱。

瞭解更多

即將舉辦的活動

檢視 Spring 社群中所有即將舉辦的活動。

檢視全部