微服務網關終結者?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個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,由鄧啟明翻譯,轉載本文請註明出處,技術原創及架構實踐文章,歡迎通過公眾號菜單「聯繫我們」進行投稿。
※你真的明白什麼是幻讀嗎?
※螞蟻金服研發的金融級分散式中間件SOFA背後的故事
TAG:高可用架構 |