微服務網關——實現篇

在《微服務網關——需求篇 》中,我們討論了微服務網關的需求;而在《微服務網關——設計篇 》中,我們討論了微服務網關的設計。本文將對微服務網關進行實現。

對於網關的開發,完全自研的難度比較大,特別是 IO 的處理。考慮到目前市面上有比較多的成熟框架,可以基於成熟的開源框架,進行二次開發。

對於 Java 來說,目前 Spring 提供了 SpringCloud Gateway(下面簡稱 SG),SG 基於 SpringWebFlux,底層默認使用的是 Netty 框架,支持高併發請求,同時提供了一些默認的組件,支持路由、限流等功能。可以基於 SG 進行二次開發。

如果對網關有特別多的自定義需求,可以直接基於 Netty 來進行更徹底的二次開發,適配自身系統的個性化需求。

本文將基於 SG 來討論網關的實現。

基於 SpringCloud Gateway 的網關設計

這裏針對前面的需求,梳理如何基於 SpringCloud Gateway 來實現。關於 SpringCloud Gateway 本身的設計和實現,會新開一篇專門討論。

SpringCloud Gateway 整體架構

SpringCloud Gateway 基於 SpringWebFlux,整體架構如下圖所示:

SG 定義了幾個概念:

SG 處理請求的大致流程如下:

GatewayHandlerMapping 判定對應的請求是否匹配某個路由。如果匹配到某個路由,則將請求交給 GatewayWebHandler 處理。Handler 調用一個 Filter 鏈來處理這個請求,具體執行流程如下:

SG 提供了 GatewayFilter 和 GlobalFilter 兩種類型的過濾器,從名字可以看出 GlobalFilter 是對全局生效的,而 GatewayFilter 是對特定請求生效的。

注意:這裏的 GlobalFilter 是針對所有匹配了 GatewayHandlerMapping 的請求生效,而不是對所有進入網關的請求生效。

假設,你在網關中編寫了一個 Controller,但是路由配置中並沒有匹配該 Controller 的路徑,那麼針對該 Controller 的請求並不會觸發任何 GlobalFilter。

SG 針對一個請求的完整流程如下圖所示:

可以看到,SG 的擴展是基於一個個的 Filter 來實現的。前面提到的大部分需求也完全可以基於 Filter 去實現,包括但不限於路由、負載均衡、認證授權、過載保護、緩存、服務重試、日誌記錄等。

這裏僅以限流爲例,來說明 SG 的擴展邏輯。其它實現請自行閱讀源碼,或關注後續內容。

限流實現

SG 提供了
RequestRateLimiterGatewayFilterFactory 過濾器支持限流,同時也支持基於 histrix 的過載保護,直接集成使用即可,具體請見 histrix 文檔。

這裏以
RequestRateLimiterGatewayFilterFactory 爲例來分析 SG 如何基於攔截器來實現 j 限流的。SG 中的限流是針對每個路由來單獨定義的,配置內容如下:

上面的配置,配置了一個路由:

上面的配置會被構建爲一個 RouteLocator 實例,該類根據配置構建 Route、Predicates、Filter 等實例。對於 Filter 來說,

RequestRateLimiterGatewayFilterFactory 核心代碼如下所示:

官方提供的分佈式限流方案是基於 redis 實現。

核心邏輯在 RedisRateLimiter 的 isAllowed() 方法中:

lua 腳本就不貼出來了,使用的是令牌桶算法。

自定義攔截器

從上面的梳理,可以看出,要編寫一個自定義的 GatewayFilter 的流程如下:

聚合服務

SG 基於 SpringWebFlux,支持編寫異步 RESTful 接口,同時提供 WebClient 異步 REST 客戶端來實現聚合服務的編寫。不過由於是編碼的形式,所以需要發佈網關。對於集羣部署的情況下,在可用性要求沒有特別嚴格的情況下,此方式可以接受。

如果聚合服務較多且發佈頻繁,可以獨立出聚合服務層。即基於 SpringWebFlux 構建微服務,使用 WebClient 來整合獨立微服務的邏輯,網關路由至對應的服務即可。

關於 WebClient 的使用方法請自行搜索,這裏就不贅述了。

非功能性需求

SG 本身就基本符合前面提到的非功能性需求

主要注意保證無狀態設計!

總結

本文及之前的「微服務網關——需求篇」和「 微服務網關——設計篇 」對微服務網關進行了梳理。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://www.toutiao.com/i6903086075166671373/