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)。

要啟用此全域性快取過濾器,只需將以下屬性設定為 truespring.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 結構任何級別的 JSON 內容主體中刪除屬性。

這些過濾器增加了強大的新功能。我們很樂意聽取您對它們如何支援您的用例以及我們如何提高您的生產力的意見。您可以在其參考文件中找到有關此新過濾器和其他功能的更多資訊。

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

其他資源

想了解更多關於 Spring Cloud 的資訊嗎?請虛擬加入我們參加 SpringOne!想了解更多關於 Spring Cloud Gateway 的產品嗎?請檢視 我們支援 Kubernetes 的商業平臺

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

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

瞭解更多

即將舉行的活動

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

檢視所有