淺談如何設計一個可用的企業級API網關

在上一篇《淺談微服務架構下的API網關》文章中, 我們介紹了API網關的概念、優勢、應用場景和選型要素, 本文我們將從API網關的架構設計與功能要素兩個方面介紹如何設計一個企業級API網關。

1. 使用API網關統一應用入口

API網關的核心設計理念是使用一個輕量級的消息網關作爲所有客戶端的應用入口,並且在 API 網關層面上實現通用的非功能性需求。如下圖所示:所有的服務通過 API 網關來暴露,這是所有客戶端訪問的唯一入口;如果一個服務要訪問另一個服務,也要通過這個網關。

API網關統一應用入口

一旦 API 網關允許客戶端消費一個受管理的 API,那麼我們就可以以受管理的 API 形式使用它來暴露這個微服務所實現的業務邏輯。API 網關可以通過HTTP、HTTPS、RPC等方式來連接內部受管理的 API,以實現 API 網關的高併發。

2. API網關架構

API網關架構

API網關爲企業的應用提供統一的應用入口, API網關隱藏了企業內部應用系統的應用細節, 從一定程度上保證了企業內部應用的安全性。 API網關爲各種應用場景提供支撐服務。

3. API網關的功能

企業級API網關應該提供下列的功能:

  1. 服務路由:外部服務訪問接口映射到對應的內部服務訪問接口。

  2. 認證授權:提供對用戶身份的認證以及用戶權限驗證,包括用戶身份的合法性、針對用戶角色的訪問授權驗證、針對用戶的訪問授權驗證、IP 黑名單驗證等。

  3. 超時處理:當 API 網關調用的內部服務響應時間超過了在自主開發的 API 網關後臺管理子系統中所設置的允許最長的超時時間時,API 網關會立即停止調用,並返回相關消息給你。

  4. 限流控制:當你通過 API 網關調用內部服務的頻率達到在某個閾值時,API 網關會立即做斷開鏈路處理。過了時間後,鏈路會自動閉合回去。

  5. 熔斷處理:熔斷處理對避免無謂的資源消耗特別有用,當通過 API 網關調用的內部服務出現異常的頻率達到某個閾值時,那麼 API 網關會做臨時熔斷處理即臨時斷開鏈路,暫時停止你對那個內部服務的調用。臨時熔斷後,過了一段時間後,鏈路會自動閉合回去。

  6. 日誌信息記錄:會記錄客戶 IP、客戶請求參數、返回結果、異常信息等信息。

  7. 負載均衡: 提供API接口的負載均衡,能夠處理API接口的高併發訪問,防止服務雪崩。

  8. 安全防護:提供嚴格的認證服務,支持算法簽名,用戶使用 API 網關提供的密鑰進行認證,沒有被授予密鑰的客戶端無法調用業務 API接口,經過認證授權的請求才能到達後端應用服務。同時SSL 加密。

  9. 灰度發佈:支持API接口線上灰度部署,減少應用版本切換風險。

4. 如何設計一個好的企業級API網關

設計一個企業級API網關時, 應該從功能需求、性能需求、高可用性、擴展性等方面進行綜合考量, 覆蓋企業的API應用場景,從而滿足企業的業務需求。下面我們將從功能、性能、高可用性和擴展性四方面進行介紹。

4.1 功能需求

企業級API網關除了上述的服務路由、認證授權、超時處理、限流控制、熔斷處理、日誌記錄、負載均衡、灰度發佈等基礎服務外,還需要提供以下的功能。

1)API 生命週期管理功能

覆蓋 API 的定義、測試、發佈和下線的整個生命週期管理,便捷的日常管理、版本管理,支持熱升級和快速回滾。並能夠提供API接口測試,預發佈,發佈等多種環境。

2)開發支持功能

提供頁面調試工具,能夠自動生成 API 文檔和 SDK,這樣可以大大降低人力成本。開源的API文檔生成方案有Swagger等。

3)流量控制功能

可控制單位時間內 API 允許被調用次數。用來保護企業的後端服務,實現業務分級和用戶分級。 支持對 API 流控,您可以根據 API 的重要程度來配置不同流控,從而保障重要業務的穩定運行; 支持用戶、應用和例外流控,您可以根據用戶的重要性來配置不同流控,從而可以保證大用戶的權益; 流控粒度:分鐘、小時、天。

4)請求管理功能

可根據配置進行參數類型、參數值(範圍、枚舉、正則、Json Schema)的校驗,減少後端對非法請求、無效請求的資源消耗和處理成本。可以在 API 網關定義參數映射規則,網關通過映射規則將後端服務通過映射翻譯成任何形式,以滿足不同用戶的不同需求,從而避免功能重複開發。

5)監控告警功能

提供實時、可視化的 API 監控,包括:調用量、調用方式、響應時間、錯誤率,讓您能夠清楚的瞭解 API 的運行狀況和用戶的行爲習慣。

支持自定義報警規則,來針對異常情況進行報警,降低故障處理時間。

提供可訂閱的數據分析報表和智能分析。

4.2 高性能設計

傳統的基於線程的併發模型(Thread-based concurrency),爲每一個請求分配一個線程或進程。這種模型編程簡單,可以將處理一個完整請求的代碼編寫在一個代碼路徑中。這種模型的弊端是,隨着線程(進程)數的上升,操作系統在這些線程(進程)之間的頻繁切換,將急劇降低系統的性能。

高性能設計

4.3 高可用設計

1) 無狀態設計原則

網關層爲保證高可用、易於擴展、快速啓動,需要設計成無狀態的。用戶的狀態數據我們通常使用session對象來封裝,網關層要設計成無狀態的,也就是說,不能由網關來負責session的維護。那由誰來維護session相關的信息呢?我們是採用cookie+session服務器的方式;

a) 用戶在登錄頁完成登錄操作後,服務器會生成一個登錄session信息,保存起來,設置個失效時間,並設置到用戶的cookie裏。

b) 用戶後續的每次請求裏會帶着這個cookie信息,服務端會對這個cookie信息進行校驗,通過了就認爲是合法用戶,執行請求操作。

2)優雅下線原則

當需要撤掉一臺網關服務的時候,不是直接結束網關進程,而是先關閉監聽套接字,但是繼續爲當前連接的客戶提供服務,所有客戶端的服務完成後,在把進程關閉。

3)Slow Start特性

當網關監聽到有一臺新的服務註冊上來時,考慮到有些服務啓動後,剛開始會有許多初始化的工作,此時服務對請求的響應速度是比較慢的。如果一開始就給這臺服務分配太多的壓力,有可能導致服務瞬間被壓垮。爲了避免這種情況,網關層需要考慮支持Slow Start特性。即,經過一段時間,逐漸把壓力增加到預設的值。

4)業務攔截擴展

我們知道,網關對請求的處理,可以分爲三個階段:接受請求、路由並轉發請求、接受服務的返回數據並返回給請求者,除此之外,還有一種情況是處理錯誤。所以我們也可以在這四個地方添加擴展點。

(1)接受到請求後;

(2)定位到一個服務,並準備轉發之前;

(3)接受到服務的返回數據,返回給客戶端之前;

(4)當服務調用失敗後。

攔截器的處理順序,可以分爲兩大類:

1. 網關平臺自帶的攔截器,例如安全校驗、日誌記錄等;

2. 網關層邏輯開發的功能,例如格式轉換等。

一般來說,網關先執行網關平臺自帶的攔截器,再執行爲了業務邏輯編寫的攔截器。當然,API網關也需要提供一種機制,可以比較容易地調整攔截器的執行順序。最簡單的一種方法,就是給每個攔截器定義一個優先級,網關按優先級順序依次調用各攔截器。

對網關層來說,它接收和處理的數據都是業務請求(Request)對象,網關層在接收到請求後,把請求封裝爲Request對象,爲了讓後續的過濾器(Filter)能夠獲得這個對象,可以考慮把Request對象保存在線程變量中。

有些攔截器,例如一些調試日誌的攔截器,通常情況下都是關閉的,只有在出現問題的時候才需要打開。爲了保證網關的高可用,網關層必須具備在線啓用或關閉攔截器的能力。一般,API網關需要提供RESTful接口方式來關閉和啓用一個攔截器。

類似這樣的命令:PUT /gateway/v1/filters/filterName?enable=value

5)API管理與動態發佈設計

對服務管理來說,分爲前端服務管理與後端服務管理。前端服務指的是網關層暴露給客戶端使用的服務API,後端服務指的是服務層提供的業務服務API。一個服務暴露給客戶端使用,除了網關層和服務層提供服務的代碼外,還需要配置前端服務與後端服務的映射關係。

網關層API調用服務層API,有多種方式。例如,可以由按照服務層API的服務契約,生成一段客戶端代碼,發佈給網關層使用。這種方式的弊端是,網關層代碼依賴於服務層代碼,服務層頻繁修改和調整接口時,導致網關層的代碼很難維護。

可以通過配置前後端服務映射的方式,解耦網關層對服務層的依賴。當服務層的API(例如服務名、參數名等)發生變化時,只需調整映射關係,無需對網關層的代碼進行調整。網關層按照映射,自動裝配服務層API所需要的數據格式。這樣,網關層團隊與服務層團隊可以相互不受干擾地開發各自的服務。

4.4 可擴展性設計

從靈活性和擴展性方面來說,在設計API網關時應該考慮如何對API網關的功能進行擴展, 網關應該提供擴展插件機制, 企業可以根據業務應用需求對網關功能進行擴展。API網關管理平臺可以對API網關業務擴展插件進行發佈與下架操作。例如Kong網關可以通過plugin接口發佈擴展插件,同時也可以通過接口下架某個插件。

總之,API網關作爲企業業務能力開放的一個應用門戶,除了具備基本的請求轉發、認證授權、路由等功能,以及高性能和高可用性外,還需具備良好的擴展性,以便於API網關能力的不斷增強。

以下是個人微信公衆號, 用於學習與交流, 歡迎大家關注。
運維前沿公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章