全網首發 Spring Cloud Gateway 添加統一前綴思路探討


1.前言

今天學習一下Spring Cloud Gateway,就先再其他博客上逛了逛。遇到有java開發者在某博客問一個問題:Spring Cloud Gateway 如何添加統一的前綴? 當時沒有在意,但是腦子里也帶着這個問題看起了文檔。隨着慢慢了解Spring Cloud Gateway 這個問題就有了一點思路。

2. Gateway工作機制

這是官方文檔上給的Spring Cloud Gateway工作流程圖。大意上是客戶端請求經過HandlerMapping的處理,如果匹配到路由(Router)就交給網關的web處理程序(Gateway Web Handler)來處理,經過一系列的調用過濾器鏈(肯定有責任鏈模式)后轉發到被代理的服務執行真正的調用邏輯。

3. Gateway Handler Mapping

根據上圖,我想找到所謂的Gateway Handler Mapping,看看是何方神聖。我找到了RoutePredicateHandlerMapping,並確定該類就是那個handler Mapping。依賴於Spring Webflux響應式web編程模型。核心方法是getHandlerInternal,通過該方法進行內部處理。

從代碼上看 就是處理了端口關系后,在request放入一些gateway特定的attribute。然后走的一個尋找路由的方法。最后通過Mono.just(webHandler)交給了一個FilteringWebHandler類型的webHandler來處理了。我們先來關注lookupRoute方法,該方法擺明了就是尋找路由。該方法的代碼不貼了。就是通過routeLocator.getRoutes()來加載所有的路由並通過斷言(Predicate)來進行匹配。匹配到就交給FilteringWebHandler 走過濾器鏈。在我明白這個流程之后,腦子里那個問題就有了眉目。

4. FilteringWebHandler

該handler就是圖中的Gateway Web Handler ,包含了一系列的GlobalFilter和GatewayFilter 來組成一個chain來處理前置和后置的邏輯。

5. 增加統一前綴的思路

在以前我們知道zuul網關是可以添加一個統一前綴的。但是Spring Cloud Gateway是沒有直接提供這個功能的。我已經搞清楚了Gateway的大致工作機制,甚至是一些細節。首先這個統一前綴肯定不能在斷言中處理。斷言是根據請求的個性化來找目的地路由的,而統一前綴是共性的。放在斷言執行后也就是FilteringWebHandler來處理就更不合適了,因為斷言執行在Filter之前。但是有一個東西我們沒有注意到。Spring Cloud Gateway的機制依賴於Spring Webflux框架的。經過查一些資料RoutePredicateHandlerMapping處理之前是可以設置WebFilter的。因此我找到了一個解決方案:在Gateway Client 和 Gateway Handler Mapping 之間定制一個WebFilter來處理統一前綴。

6. 思路實現

機制是這樣的,請求帶統一前綴請求經過我定制的WebFilter去掉前綴(當然你可以加一些其他你需要的邏輯)然后交給Gateway Handler Mapping處理。代碼如下

經過測試有效。

7. 總結

這里其實重點不是如何來實現這個功能,我想傳達的是一個解決問題的思路。如何從框架的工作機制出發來分析你所需要解決的問題。找到那個合適的切入點。清晰的思路對於解決問題來說至關重要。其實我現在對Spring Cloud Gateway和Spring Webflux 都並不是很熟練,但是依然找了一個解決問題的方法。不知道你有沒有更好的方法呢?相關代碼已經上傳到碼雲倉庫:https://gitee.com/felord/tino-cloud.git

關注公眾號:碼農小胖哥,獲取更多資訊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM