歡迎光臨
每天分享高質量文章

微服務網關終結者?Spring Cloud推出新成員Spring Cloud Gateway

導語:Spring Cloud Gateway基於Spring Boot 2,該專案提供了一個構建在Spring 生態之上的 API 網關。Spring Cloud Gateway旨在提供一種簡單而有效的途徑來發送API。

當傳統的服務(例如資料庫、訊息佇列、搜索引擎)在Cloud Foundry生態系統中廣泛的應用和交易,有兩種你可能不知道的服務發現方式。捲(Volume)服務[1]允許你做一個持久掛載的系統到你的應用。路由服務[2]允許攔截到你應用的所有HTTP流量。

路由服務

路由服務可以被用於很多目的,例如日誌、限流、認證,從而做到應用無感知。

首先,讓我們瞭解一下路由服務的工作原理。當路由服務系結到應用,路由器將攔截到應用的所有請求,添加一些HTTP頭以及保證請求完整性的簽名,並將請求路由到對應服務(或者修改URL,或者僅僅傳回一個錯誤的響應)。路由服務能做的事情請查看路由服務文件。

簡單日誌服務

這一節,我們學習如何使用Spring Cloud團隊推出的API網關Spring Cloud Gateway構建一個簡單的路由服務。這是一個簡單的服務,它僅僅在日誌中記錄請求的詳細信息,然後將請求轉發到標的地址(類似路由服務文件中的Spring Boot實體[3])。

創建專案

首先,創建一個新的Spring專案。你必須保證使用Spring Boot 2.x版本(當前最新版本2.0.0 RC1),並且包含Gateway和Reactive Web的依賴。在這個例子中,我根據自己的偏愛使用Gradle,當然你也可以使用Maven。

路由謂詞

接下來,我們需要設置網關路由,用於處理請求。如路由服務文件在Headers部分提到的,這裡有3個essay-header用於標識一個路由服務請求:

  • X-CF-Forwarded-Url:請求的標的URL

  • X-CF-Proxy-Signatur:驗證請求用的token

  • X-CF-Proxy-Metadata:解析和驗證X-CF-Proxy-Signature的幫助信息

上面這個Spring Cloud Gateway路由服務圍繞謂詞構建。在這個例子中,有3個基於Predicate的簡單Header。如果一個請求,這3個謂詞全都匹配,那我們轉發該請求到http://google.com:80(很明顯真實的場景不能這麼做,後面我們將使用filter更新標的地址)。我們使用./gradlew bootRun命令啟動服務,並且使用http客戶端驗證服務是否正常工作。

如你所見,路由服務處理了這3個Header,並且如我們所期待的將請求轉發到google了(google傳回了301作為響應)。

日誌Filter

接下來,我們構建一個簡單的Filter,用於記錄進來的請求的一些信息。

最後呼叫chain.filter(exchange),表明這個Filter已經處理完成,並且將請求傳給Filter鏈中的下一個Filter進行處理,或者如果這是鏈中最後一個Filter,則對請求放行。接下來,我們需要確保當路由服務處理請求時會呼叫Filter。

如你所見,我們使用filters()方法增加了日誌過濾器。f是GatewayFilterSpec[4]類的實體,包含了常用filters的簡便方法,例如添加Header、轉發,或者開啟Hystrix[5]。

如果我們使用HTTP客戶端再次測試,我們將看到我們日誌中的詳細信息:

轉發到標的URL

最後,我們需要確保請求被轉發到了標的URI,而不是google。我們能使用另外的Filter完成這個目的。

這個值從X-CF-Forwarded-Url中獲取,並且儲存在Spring Cloud Gateway的特殊屬性中,用於發送最終的請求。如果產生了異常,網關將停止處理請求,並且傳回一個500。註意,和其他型別的路由服務一樣,這是用於拒絕請求的通用樣式。如果你需要拒絕請求,你可以僅僅傳回500狀態碼,同時停止處理請求。

現在,在路由中寫一個新的Filter:

ROUTE_TO_URL_FILTER_ORDER是一個常量,表明RouteToRequestUrlFilter型別的Filter在運行。我們需要確保我們前面定義的Filter 在它之後運行,這樣我們的GATEWAY_REQUEST_URL_ATTR就不會被改寫。另外,你可能要註意,我們從f.add換成了f.filter。這是因為當前版本的Spring Cloud Gateway不允許通過add方法進行設置。

我們通過HTTP客戶端再驗證一次:

註意,我們通過X-CF-Forwarded-Url的Header屬性使用reddit替換掉了google。

部署

到這裡,路由服務就可以部署了。你應該構建應用(Gradle用戶使用./gradlew build命令),參照路由服務文件中的教程[6]部署。

總結

Spring Cloud Gateway剛出來不是很久,但是對於那些想在Cloud Foundry應用前面做一層處理的Java開發者來說,是非常有用的選擇。如果你想看簡單路由服務的最終原始碼,在這裡[7]。另外,有必要看看Spring Gloud Gateway的文件,包含了很多當前教程沒有提到的有用的謂詞和Filter。

文中鏈接


[1] https://docs.cloudfoundry.org/devguide/services/using-vol-services.html

[2] https://docs.cloudfoundry.org/services/route-services.html

[3] https://github.com/nebhale/route-service-example

[4] https://github.com/spring-cloud/spring-cloud-gateway/blob/v2.0.0.M6/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java

[5] https://github.com/Netflix/Hystrix

[6] https://docs.cloudfoundry.org/services/route-services.html#tutorial

[7] https://github.com/Fitzoh/simple-gateway-route-service


本文作者Andrew Fitzgerald,由鄧啟明翻譯,轉載本文請註明出處,技術原創及架構實踐文章,歡迎通過公眾號選單「聯繫我們」進行投稿。


相關閱讀:



高可用架構

改變互聯網的構建方式

長按二維碼 關註「高可用架構」公眾號

赞(0)

分享創造快樂