如果讓我設計一套,TPS百萬級API網關!

作者:小傅哥
部落格://bugstack.cn

沉澱、分享、成長,讓自己和他人都能有所收穫!😄

是滴,小傅哥又要準備搞事情了!這次準備下手API網關項目,因為這是所有互聯網大廠都有的一個核心服務,承接著來自用戶的滴滴打車、美團外賣、京東購物、微信支付,更是大促期間千萬級訪問量的核心系統。

🤔 那麼它是一個什麼樣的項目呢?為什麼會有它的存在?它是怎麼設計實現的呢?都用到了哪些技術棧呢?

一、前言:網關是啥東西

在電腦網路中,網關(Gateway)是轉發其他伺服器通訊數據的伺服器,接收從客戶端發送來的請求時,它就像自己擁有資源的源伺服器一樣對請求進行處理。

而API網關也是隨著對傳統龐大的單體應用(All in one)拆分為眾多的微服務(Microservice)以後,所引入的統一通訊管理系統。用於運行在外部http請求與內部rpc服務之間的一個流量入口,實現對外部請求的協議轉換、參數校驗、鑒權、切量、熔斷、限流、監控、風控等各類共性的通用服務。

二、大廠:為啥都做網關

各大廠做網關,其實做的就是一套統一方案。將分散式微服務下的RPC到HTTP通訊的同類共性的需求,凝練成通用的組件服務,減少在業務需求場景開發下,非業務需求的同類技術訴求的開發成本。

那麼以往沒有網關的時候怎麼做,基本的做法就是再 RPC 服務之上再開發一個對應的 WEB 服務,這些 WEB 服務可以是 Spring MVC 工程,在 Spring MVC 工程中調用 RPC 服務,最終提供 HTTP 介面給到 H5、Web、小程式、APP 等應用中進行使用。如圖 1-1 所示

图 1-1 从传统方式到网关设计

傳統開發 WEB 服務的幾個問題:

  • 問題1:每一個 WEB 應用,都需要與之匹配申請一套工程、域名、機器等資源,一直到部署,研發效率降低,維護成本增加。
  • 問題2:每一個 WEB 應用,都會有所涉及共性需求,限流、熔斷、降級、切量等訴求,維護程式碼成本增加。
  • 問題3:每一個 WEB 應用,在整個使用生命周期內,都會涉及到文檔的維護、工程的調試、聯調的訴求,類似刀耕火種一樣的開發勢必降低研發效率。

所以:綜上在微服務下的傳統開發所遇到的這些問題,讓各個大廠都有了自己自研網關的訴求,包括;阿里、騰訊、百度、美團、京東、網易、亞馬遜等,都有自己成熟的 API 網關解決方案。畢竟這可以降低溝通成本、提升研發效率、提升資源利用率。

三、網關:系統架構設計

如果希望實現一個能支撐百億級吞吐量的網關,那麼它就應該是按照分散式架構思維做去中心化設計,支援橫向擴展。讓每一台網關服務都成為一個算力,把不同的微服務RPC介面,按照權重策略計算動態分配到各個算力組中,做到分散式運算的能力。

此外從設計實現上,要把網關的通訊模組、管理服務、SDK、註冊中心、運營平台等依次分開單獨開發實現,這樣才能進行獨立的組合包裝使用。

這就像為什麼 ORM 框架在開發的時候不是與 Spring 強綁定在一起,而是開發一個獨立的組件,當需要有 Spring 融合使用的時候,再單獨開發一個 Mybatis-Spring 來整合服務。

所以在這裡設計網關的時候也是同樣的思路,就像官網的通訊不應該一開始就把 Netty 相關的服務全部綁定到 Spring 容器,這樣即增加了維護成本,也降低了系統的擴展性。

諸如此類的軟體架構設計,都會在這套網關微服務架構中體現,整體架構如圖 1-2 所示

图 1-2 网关架构设计

整個API網關設計核心內容分為這麼五塊;

  • 第一塊:是關於通訊的協議處理,也是網關最本質的處理內容。這裡需要藉助 NIO 框架 Netty 處理 HTTP 請求,並進行協議轉換泛化調用到 RPC 服務返回數據資訊。
  • 第二塊:是關於註冊中心,這裡需要把網關通訊系統當做一個算力,每部署一個網關服務,都需要向註冊中心註冊一個算力。而註冊中心還需要接收 RPC 介面的註冊,這部分可以是基於 SDK 自動掃描註冊也可以是人工介入管理。當 RPC 註冊完成後,會被註冊中心經過AHP權重計算分配到一組網關算力上進行使用。
  • 第三塊:是關於路由服務,每一個註冊上來的Netty通訊服務,都會與他對應提供的分組網關相關聯,例如:wg/(a/b/c)/user/... a/b/c 需要匹配到 Nginx 路由配置上,以確保不同的介面調用請求到對應的 Netty 服務上。PS:如果對應錯誤或者為啟動,可能會發生類似B站事故。
  • 第四塊:責任鏈下插件模組的調用,鑒權、授信、熔斷、降級、限流、切量等,這些服務雖然不算是網關的定義下的內容,但作為共性通用的服務,它們通常也是被放到網關層統一設計實現和使用的。
  • 第五塊:管理後台,作為一個網關項目少不了一個與之對應的管理後台,用戶介面的註冊維護、mock測試、日誌查詢、流量整形、網關管理等服務。

綜上系統微服務模組結構如下:

序號 系統 描述
1 api-gateway-core 網關核心系統:用於網路通訊轉換處理,承接http請求,調用RPC服務,責任鏈模組調用
2 api-gateway-admin 網關管理系統:用於網關介面後台管理,註冊下線停用控制
3 api-gateway-sdk 網關註冊組件:用於註解方式採集介面,發送消息註冊介面
4 api-gateway-center 網關註冊中心:提供網關註冊中心服務,登記網關介面資訊
5 api-gateway-test-provider 網關測試工程:提供RPC介面
6 api-gateway-test-consumer 網關測試工程:消費RPC介面

四、演示:網關運行效果

趁著周末假期小傅哥已經做了一部分的功能實現,就像小傅哥以前《手寫Spring》、《手寫Mybatis》一樣,此項目也是漸進式的逐步完成各個模組功能的開發。並參照優秀源碼級的項目架構設計,運用抽象和分治的設計技巧,解決功能間的耦合調用和服務設計。同時也結合設計原則和相應場景下的設計模式,開發出高品質易於迭代和維護的程式碼。部分程式碼實現和運行如圖 1-3 所示

图 1-3 网关运行效果

  • 左側是API網關核心通訊模組,右側是RPC(Dubbo)服務。通過對網頁端發起的 http 請求,經過API網關的協議轉換和對RPC的泛化調用包裝結果數據並返回到頁面,就是中間這張圖的運行效果了。
  • 左側工程的實現,以漸進式分拆模組逐步完成,例如: core-01(Netty通訊)、core-02(泛化調用)、core-03(執行器)等,讓每一個對API網關感興趣的讀者都能從中學習到;架構的分層、功能的設計、程式碼的實現。