本文將詳細分析SpringCloud Gateway是如何實現的。
架構SpringCloud Gateway(下面簡稱SG)基於SpringWebFlux,整體架構如下圖所示:
SG定義了幾個概念:
路由(Route):路由是閘道器的基本構成單元。它由一個ID、一個目標URL、一組謂詞以及一組過濾器組成。當謂詞判定為true時,表示請求與對應路由匹配謂詞(Predicate):Java8函式式謂詞。輸入引數是Spring框架封裝的ServerWebExchange物件。開發人員可以基於此物件來匹配HTTP請求的任意內容,比如請求頭或請求引數過濾器(Filter):由特定工廠類構造的一組Spring框架提供的GatewayFilter物件。過濾器可以在請求或響應被處理前/後對其進行修改。架構流程一個請求被SG處理的大致流程如下所示:
GatewayHandlerMapping判定對應的請求是否匹配某個路由。如果匹配到某個路由,則將請求交給GatewayWebHandler處理,Handler呼叫一個Filter鏈來處理這個請求:首先,會執行「pre」過濾器的邏輯然後執行請求處理luoji最後再執行「post」過濾器的邏輯如果沒有匹配到路由,則不執行對應處理下面以一個具體的例子來進行說明。
SG支援基於Java編碼方式的配置以及基於配置檔案的配置。
Java編碼方式配置配置檔案配置這兩個配置是等價的。
啟動流程SG是基於SpringBoot構建的,啟動相關配置可見專案中的spring.factories檔案。由於涉及的配置很多,我們直接定位到核心BeanHandlerMapping:SG構建的HandlerMapping例項是RoutePredicatehandlerMappingWebHandler:構建的WebHandler為FilteringWebHandler,它接收List<GlobalFilter>作為引數Route:路由構建由RouteDefinitionRouteLocator例項來處理,它基於路由配置(即上面的配置檔案)來構建Route例項從上面的程式碼可以看到,最終Filter,WebHandler(注意,這裡是GlobalFilter),Route都作為直接引數或間接引數傳遞給了RoutePredicateHandlerMapping。所以我們可以從RoutePredicateHandlerMapping來梳理SG的執行流程。RoutePredicateHandlerMapping是HandlerMapping的一個例項,HandlerMapping歸屬於SpringWebFlux,這裡不做說明,請自行查閱相關資料。
請求處理流程我們結合上面的配置檔案,以及SG具體的例項來說明SG對請求的處理流程:
當請求到達SG後,首先由RoutePredicateHandlerMapping來處理請求(前面的流程由SpringWebFlux處理,不在討論範圍內)首先根據請求從RouteLocator中查詢符合規則的路由,返回Route返回的Route設定為exchange的屬性返回構造時傳入的WebHandler執行WebHandler從exchange的屬性中獲取Route從Route中獲取GatewayFilter鏈與GlobalFilter進行整合,排序,構成完成的Filter遍歷執行Filter其中部分GlobalFilter有執行Service的功能,例如NettyRoutingFilter。這類Filter負責將請求轉發給對應的Service進行具體的邏輯處理關鍵流程程式碼1處即根據exchange從RouteLocator中查詢匹配的路由1.1處根據謂詞進行路由匹配2處,將路由設定到exchange的屬性中3處,從exchange的屬性中獲取路由4處,從路由中獲取GatewayFilter列表5、6、7處,將GlobalFilter與GatewayFilter整合到一起,按Order排序8處,執行Filter執行服務SG中服務的執行也是透過GlobalFilter來執行的,SG中預設配置了一些GlobalFilter,下面列出了部分。
LoadBalancerClientFilter:負載均衡NettyRoutingFilter:執行服務NettyWriteResponseFilter:回寫響應先看LoadBalancerClientFilter,核心原始碼如下:
1處,如果配置的目標url不是lb開頭的,則忽略。即對lb://格式的url進行負載均衡處理2處,根據exchange選擇對應的Service,這裡實現了負載均衡邏輯,具體自行閱讀原始碼3處,構建真實的Service請求地址4處,將請求設定到exchange的屬性中NettyRoutingFilter在LoadBalancerClientFilter之後,用於執行服務。
1處,從exchange中獲取服務請求2處,構建請求引數,包括method,url和chunkedTransfer(程式碼略)3處,透過httpClient傳送請求呼叫4處,將響應和連線資訊設定到了exchange屬性中最後由NettyWriteResponseFilter來處理響應。
1處,首先注意到,這個Filter是個post過濾器,即是來處理響應的2處,從exchange中獲取Connection3處,從連接獲取服務響應4處,將服務響應寫入到閘道器響應中參考資料SpringCloud Gateway官方文件SpringCloud Gateway 原始碼