百億流量微服務網關的設計與實現

API 網關概述

“計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決。”

——David Wheeler

分佈式服務架構、微服務架構與 API 網關

1. 什麼是 API 網關(API Gateway)

其實,網關跟面向服務架構(Service Oriented Architecture,SOA)和微服務架構(MicroServicesArchitecture,MSA)有很深的淵源。

十多年以前,銀行等金融機構完成全國業務系統大集中以後,分散的系統都變得集中,也帶來了各種問題:業務發展過快如何應對,對接系統過多如何集成和管理。爲了解決這些問題,業界實現了作用於渠道與業務系統之間的中間層網關,即綜合前置系統,由其適配各類渠道和業務,處理各種協議接入、路由與報文轉換、同步異步調用等操作,如圖 7-1 所示。

                           

圖 7-1

人們基於 SOA 的理念,在綜合前置的基礎上,進一步增加了服務的元數據管理、註冊、中介、編排、治理等功能,逐漸形成了企業服務總線(ESB,EnterpriseService Bus)。例如普元公司推出的 PrimetonESB 就是一個由本書作者之一參與開發的總線系統,如圖 7-2 所示。

圖 7-2

面向服務架構(SOA)是一種建設企業 IT 生態系統的架構指導思想。SOA 的關注點是服務,服務最基本的業務功能單元由平臺中立性的接口契約來定義。通過將業務系統服務化,可以將不同模塊解耦,各種異構系統間可以輕鬆實現服務調用、消息交換和資源共享。不同於以往的孤立業務系統,SOA 強調整個企業 IT 生態環境是一個大的整體。整個 IT 生態中的所有業務服務構成了企業的核心 IT 資源。各個系統的業務拆解爲不同粒度和層次的模塊和服務,服務可以組裝到更大的粒度,不同來源的服務可以編排到同一個處理流程中,實現非常複雜的集成場景和更加豐富的業務功能。

SOA 從更高的層次對整個企業 IT 生態進行統一的設計與管理,應用軟件被劃分爲具有不同功能的服務單元,並通過標準的軟件接口把這些服務聯繫起來,以 SOA 架構實現的企業應用可以更靈活快速地響應企業的業務變化,實現新舊軟件資產的整合和複用,降低軟件整體擁有成本。

當然基於 ESB 這種集中式管理的 SOA 方案也存在種種問題,特別是在面向互聯網技術領域的爆發式發展的情況下。

2. 分佈式服務架構、微服務架構與 API 網關

近年來,隨着互聯網技術的飛速發展,爲了解決以 ESB 爲代表的集中式管理的 SOA 方案的種種問題,以 Apache Dubbo(2011 年開源後)與 Spring Cloud 爲代表的分佈式服務化技術的出現,給了 SOA 實現的另外一個選擇:去中心化的分佈式服務架構(DSA)。分佈式服務架構技術不再依賴於具體的服務中心容器技術(比如 ESB),而是將服務尋址和調用完全分開,這樣就不需要通過容器作爲服務代理。

之後又在此基礎上隨着 REST、Docker 容器化、領域建模、自動化測試運維等領域的發展,逐漸形成了微服務架構(MSA)。在微服務架構裏,服務的粒度被進一步細分,各個業務服務可以被獨立地設計、開發、測試、部署和管理。這時,各個獨立部署單元可以選擇不同的開發測試團隊維護,可以使用不同的編程語言和技術平臺進行設計,但是要求必須使用一種語言和平臺無關的服務協議作爲各個單元之間的通信方式,如圖 7-3 所示。

圖 7-3

在微服務架構中,由於系統和服務的細分,導致系統結構變得非常複雜,RESTAPI 由於其簡單、高效、跨平臺、易開發、易測試、易集成,成爲不二選擇。此時一個類似綜合前置的系統就產生了,這就是 API 網關(API Gateway)。API 網關作爲分散在各個業務系統微服務的 API 聚合點和統一接入點,外部請求通過訪問這個接入點,即可訪問內部所有的 REST API 服務。

跟 SOA/ESB 類似,企業內部向外暴露的所有業務服務能力,都可以通過 API 網關上管理的 API 服務得以體現,所以 API 網關上也就聚合了企業所有直接對外提供的 IT 業務能力。

3. API 網關的技術趨勢

Spring Cloud 和 SOA 非常火,MSA、gRPC、Gateway 都有着非常高的關注度,通過 GitHub 的搜索來看,Gateway 類型的項目也非常熱門。

從 https://github.com/search?o=desc&p=1&q=gateway&s=stars&type=Repositories 上可以看到,前 10 頁的 100 個項目,使用 Go 語言實現的 Gateway 差不多佔一半,從語言分類上來看:Go>Node.js/JavaScript>Java>Lua>C/C++>PHP>Python/Ruby/Perl。

API 網關的定義、職能與關注點

1. API 網關的定義

網關的角色是作爲一個 API 架構,用來保護、增強和控制對於 API 服務的訪問(The role of a Gateway in anAPI architecture is to protect, enrich and control access to API services.)。

引用自 https://github.com/strongloop/microgateway。

API 網關是一個處於應用程序或服務(提供 REST API 接口服務)之前的系統,用來管理授權、訪問控制和流量限制等,這樣 REST API 接口服務就被 API 網關保護起來,對所有的調用者透明。因此,隱藏在 API 網關後面的業務系統就可以專注於創建和管理服務,而不用去處理這些策略性的基礎設施。

這樣,網關係統就可以代理業務系統的業務服務 API。此時網關接收外部其他系統的服務調用請求,也需要訪問後端的實際業務服務。在接收請求的同時,可以實現安全相關的系統保護措施。在訪問後端業務服務的時候,可以根據相關的請求信息做出判斷,路由到特定的業務服務上,或者調用多個服務後聚合成新的數據返回給調用方。網關係統也可以把請求的數據做一些過濾和預處理,同理也可以把返回給調用者的數據做一些過濾和預處理,即根據需要對請求頭 / 響應頭、請求報文 / 響應報文做一些修改。如果不做這些額外的處理,則簡單直接代理服務 API 功能,我們稱之爲透傳。

同時,由於 REST API 的語言無關性,基於 API 網關,後端服務可以是任何異構系統,不論 Java、.NET、Python,還是 PHP、ROR、Node.js 等,只要支持 REST API,就可以被 API 網關管理起來。

2. API 網關的職能

API 網關的職能如圖 7-4 所示。

圖 7-4

一般來說,API 網關有四大職能。

3. API 網關的關注點

API 網關並不是一個典型的業務系統,而是一個爲了讓業務系統更專注於業務服務本身,給 API 服務提供更多附加能力的一箇中間層。

在設計和實現 API 網關時,需要考慮兩個目標:

(1)開發維護簡單,節約人力成本和維護成本。即應選擇成熟的簡單可維護的技術體系。

(2)高性能,節約設備成本,提高系統吞吐能力。要求我們需要針對 API 網關的特點進行一些特定的設計和權衡。

當併發量小的時候,這些都不是問題。一旦系統的 API 訪問量非常大,這些都會成爲關鍵的問題。

海量併發的 API 網關最重要的三個關注點:

(1)保持大規模的 inbound 請求接入能力(長短連接),比如基於 Netty 實現。

(2)最大限度地複用 outbound 的 HTTP 連接能力,比如基於 HttpClient4 的異步 HttpClient 實現。

(3)方便靈活地實現安全、驗證、過濾、聚合、限流、監控等各種策略。

API 網關的分類與技術分析

1. API 網關的分類

如果對上述的目標和關注點進行更深入的思考,那麼所有需要考慮的問題和功能可以分爲兩類。

隨着互聯網的複雜業務系統的發展,這兩類功能集合逐漸形成了現在常見的兩種網關係統:流量網關和業務網關,如圖 7-5 所示。

圖 7-5

2. 流量網關與 WAF

我們定義全局性的、跟具體的後端業務系統和服務完全無關的策略網關,即爲流量網關。這樣流量網關關注全局流量的穩定與安全,比如防止各類 SQL 注入、黑白名單控制、接入請求到業務系統的負載均衡等,通常有如下通用性的具體功能:

通過這個功能清單,我們可以發現,流量網關的功能跟 Web 應用防火牆(WAF)非常類似。WAF 一般是基於 Nginx/OpenResty 的 ngx_lua 模塊開發的 Web 應用防火牆。

一般 WAF 的代碼很簡單,專注於使用簡單、高性能和輕量級。簡單地說就是在 Nginx 本身的代理能力以外,添加了安全相關功能。用一句話描述其原理,就是解析 HTTP 請求(協議解析模塊),規則檢測(規則模塊),做不同的防禦動作(動作模塊),並將防禦過程(日誌模塊)記錄下來。

一般的 WAF 具有如下功能:

以上 WAF 的內容主要參考如下兩個項目:

流量網關的開源實例還可以參考著名的開源項目 Kong(基於 OpenResty)。

3. 業務網關

我們定義針對具體的後端業務系統,或者是服務和業務有一定關聯性的策略網關,即爲業務網關。比如,針對某個系統、某個服務或某個用戶分類的流控策略,針對某一類服務的緩存策略,針對某個具體系統的權限驗證方式,針對某些用戶條件判斷的請求過濾,針對具體幾個相關 API 的數據聚合封裝,等等。

業務網關一般部署在流量網關之後、業務系統之前,比流量網關更靠近業務系統。我們大部分情況下說的 API 網關,狹義上指的是業務網關。如果系統的規模不大,我們也會將兩者合二爲一,使用一個網關來處理所有的工作。

開源****網關的分析與調研

常見的開源網關介紹

常見的開源網關如圖 7-6 所示。

圖 7-6

按照使用範圍、成熟度等來劃分,主流的有 4 個:OpenResty、Kong、Zuul/Zuul 2、Spring Cloud Gateway,此外 fagongzi API 網關最近也獲得不少關注。

1. Nginx+Lua 網關

OpenResty

項目地址:http://openresty.org/

OpenResty 基於 Nginx,集成了 Lua 語言和 Lua 的各種工具庫、可用的第三方模塊,這樣我們就在 Nginx 既有的高效 HTTP 處理的基礎上,同時獲得了 Lua 提供的動態擴展能力。因此,我們可以做出各種符合我們需要的網關策略的 Lua 腳本,以其爲基礎實現網關係統。

Kong

項目地址:https://konghq.com / 與 https://github.com/kong/kong

Kong 基於 OpenResty,是一個雲原生、快速、可擴展、分佈式的微服務抽象層(MicroserviceAbstraction Layer),也叫 API 網關(API Gateway),在 Service Mesh 裏也叫 API 中間件(API Middleware)。

Kong 開源於 2015 年,核心價值在於其高性能和擴展性。從全球 5000 強的組織統計數據來看,Kong 是現在依然在維護的、在生產環境使用最廣泛的網關。

核心優勢如下。

ABTestingGateway

項目地址:https://github.com/CNSRE/ABTestingGateway

ABTestingGateway 是一個可以動態設置分流策略的網關,關注與灰度發佈相關的領域,基於 Nginx 和 ngx-lua 開發,使用 Redis 作爲分流策略數據庫,可以實現動態調度功能。

ABTestingGateway 是新浪微博內部的動態路由系統 dygateway 的一部分,目前已經開源。在以往的基於 Nginx 實現的灰度系統中,分流邏輯往往通過 rewrite 階段的 if 和 rewrite 指令等實現,優點是性能較高,缺點是功能受限、容易出錯,以及轉發規則固定,只能靜態分流。ABTestingGateway 則採用 ngx-lua,通過啓用 lua-shared-dict 和 lua-resty-lock 作爲系統緩存和緩存鎖,系統獲得了較爲接近原生 Nginx 轉發的性能。

功能特性如下。

據瞭解,美團網內部的 Oceanus 也是基於 Nginx 和 ngx-lua 擴展實現的,主要提供服務註冊與發現、動態負載均衡、可視化管理、定製化路由、安全反扒、Session ID 複用、熔斷降級、一鍵截流和性能統計等功能。

2. 基於 Java 語言的網關

Zuul/Zuul2

項目地址:https://github.com/Netflix/zuul

Zuul 是 Netflix 開源的 API 網關係統,它的主要設計目標是動態路由、監控、彈性和安全。

Zuul 的內部原理可以簡單看作很多不同功能 filter 的集合(作爲對比,ESB 也可以簡單被看作管道和過濾器的集合)。這些過濾器(filter)可以使用 Groovy 或其他基於 JVM 的腳本編寫(當然 Java 也可以編寫),放置在指定的位置,然後可以被 Zuul Server 輪詢,發現變動後動態加載並實時生效。Zuul 目前有 1.x 和 2.x 兩個版本,這兩個版本的差別很大。

Zuul 1.x 基於同步 I/O,也是 Spring Cloud 全家桶的一部分,可以方便地配合 Spring Boot/SpringCloud 配置和使用。

在 Zuul 1.x 裏,Filter 的種類和處理流程如圖 7-7 所示,最主要的就是 pre、routing、post 這三種過濾器,分別作用於調用業務服務 API 之前的請求處理、直接響應、調用業務服務 API 之後的響應處理。

Zuul 2.x 最大的改進就是基於 Netty Server 實現了異步 I/O 來接入請求,同時基於 Netty Client 實現了到後端業務服務 API 的請求。這樣就可以實現更高的性能、更低的延遲。此外也調整了 Filter 類型,將原來的三個核心 Filter 顯式命名爲 Inbound Filter、Endpoint Filter 和 Outbound Filter,如圖 7-8 所示。

圖 7-7

圖 7-8

Zuul 2.x 的核心功能:服務發現、負載均衡、連接池、狀態分類、重試、請求憑證、HTTP/2、TLS、代理協議、GZip、WebSocket。

SpringCloud Gateway

項目地址:https://github.com/spring-cloud/spring-cloud-gateway/

Spring Cloud Gateway 基於 Java 8、Spring 5.0、Spring Boot 2.0、Project Reactor,發展得比 Zuul 2 要早,目前也是 Spring Cloud 全家桶的一部分。

Spring Cloud Gateway 可以看作一個 Zuul 1.x 的升級版和代替品,比 Zuul 2 更早地使用 Netty 實現異步 I/O,從而實現了一個簡單、比 Zuul 1.x 更高效的、與 Spring Cloud 緊密配合的 API 網關。

Spring Cloud Gateway 裏明確地區分了 Router 和 Filter,內置了非常多的開箱即用功能,並且都可以通過 Spring Boot 配置或手工編碼鏈式調用來使用。

比如內置了 10 種 Router,直接配置就可以隨心所欲地根據 Header、Path、Host 或 Query 來做路由。

核心特性:

graviteeGateway

項目地址:https://gravitee.io / 與 https://github.com/gravitee-io/gravitee-gateway

KaazingWebSocket Gateway

項目地址:

https://github.com/kaazing/gateway 與 https://kaazing.com/products/websocket-gateway/

Kaazing WebSocket Gateway 是一個專門針對和處理 WebSocket 的網關,宣稱提供世界一流的企業級 WebSocket 服務能力。具體如下特性:

Dromara soul

項目地址:https://github.com/Dromara/soul。

Soul 是一個異步的、高性能的、跨語言的、響應式的 API 網關,提供了統一的 HTTP 訪問。

3. 基於 Go 語言的網關

fagongzi

項目地址:https://github.com/fagongzi/gateway

fagongzi Gateway 是一個 Go 實現的功能全面的 API 網關,自帶了一個 Rails 實現的 Web UI 管理界面。

功能特性:流量控制、熔斷、負載均衡、服務發現、插件機制、路由(分流,複製流量)、API 聚合、API 參數校驗、API 訪問控制(黑白名單)、API 默認返回值、API 定製返回值、API 結果 Cache、JWT 認證、API Metric 導入 Prometheus、API 失敗重試、後端 Server 的健康檢查、開放管理 API(gRPC、RESTful)、支持 WebSocket 協議。

Janus

項目地址:https://github.com/hellofresh/janus

Janus 是一個輕量級的 API 網關和管理平臺,能實現控制誰、什麼時候、如何訪問這些 REST API,同時它也記錄了所有的訪問交互細節和錯誤。使用 Go 實現 API 網關的一個好處在於,一般只需要一個單獨的二進制文件即可運行,沒有複雜的依賴關係。功能特性:

4. .NET

Ocelot

項目地址:https://github.com/ThreeMammals/Ocelot

功能特性:路由、請求聚合、服務發現(基於 Consul 或 Eureka)、服務 Fabric、WebSockets、驗證與鑑權、流控、緩存、重試策略與 QoS、負載均衡、日誌與跟蹤、請求頭、Query 字符串轉換、自定義的中間處理、配置和管理 REST API。

5. Node.js

Express Gateway

項目地址:

https://github.com/ExpressGateway/express-gateway 與 https://www.express-gateway.io/

Express Gateway 是一個基於 Node.js 開發,使用 Express 和 Express 中間件實現的 REST API 網關。

功能特性:

MicroGateway

項目地址:

https://github.com/strongloop/microgateway 與 https://developer.ibm.com/apiconnect

StrongLoop 是 IBM 的一個子公司,MicroGateway 網關基於 Node.js/Express 和 Nginx 構建,作爲 IBM API Connect,同時也是 IBM 雲生態的一部分。MicroGateway 是一個聚焦於開發者,可擴展的網關框架,它可以增強我們對微服務和 API 的訪問能力。

核心特性:

此外,MicroGateway 還有幾個特性:

核心架構如圖 7-9 所示。

圖 7-9

四大開源網關的對比分析

1. OpenResty/Kong/Zuul 2/SpringCloud Gateway 重要特性對比

各項指標對比如表 7-1 所示。

以限流功能爲例:

對 Zuul/Zuul 2/Spring Cloud Gateway 的一些功能點分析可以參考 Spring Cloud Gateway 作者 Spencer Gibb 的文章:https://spencergibb.netlify.com/preso/detroit-cf-api-gateway-2017-03/。

2. OpenResty/Kong/Zuul 2/SpringCloudGatew****ay 性能測試對比

分別使用 3 臺 4Core、16GB 內存的機器,作爲 API 服務提供者、Gateway、壓力機,使用 wrk 作爲性能測試工具,對 OpenResty/Kong/Zuul 2/SpringCloud Gateway 進行簡單小報文下的性能測試,如圖 7-10 所示。

圖 7-10

圖中縱座標軸是 QPS,橫軸是一個 Gateway 的數據,每根線是一個場景下的不同網關數據,測試結論如下:

開源網關的技術總結

1. 開源網關的測試分析

脫離場景談性能,都是 “耍流氓”。性能就像溫度,不同的場合下標準是不一樣的。同樣是 18 攝氏度,老人覺得冷,年輕人覺得合適,企鵝覺得熱,冰箱裏的蔬菜可能容易壞了。

同樣基準條件下,不同的參數和軟件,相對而言的橫向比較纔有價值。比如同樣的機器(比如 16GB 內存 / 4 核),同樣的 Server(用 Spring Boot,配置路徑爲 api/hello,返回一個 helloworld),同樣的壓測方式和工具(比如用 wrk,10 個線程,20 個併發連接)。我們測試直接訪問 Server 得到的極限 QPS(QPS-Direct,29K);配置了一個 Spring Cloud Gateway 做網關訪問的極限 QPS(QPS-SCG,11K);同樣方式配置一個 Zuul 2 做網關壓測得到的極限 QPS(QPS-Zuul2,13K);Kong 得到的極限 QPS(QPS-Kong,21K);OpenResty 得到的極限 QPS(QPS-OR,19K)。這個對比就有意義了。

Kong 的性能非常不錯,非常適合做流量網關,並且對於 service、route、upstream、consumer、plugins 的抽象,也是自研網關值得借鑑的。

對於複雜系統,不建議業務網關用 Kong,或者更明確地說是不建議在 Java 技術棧的系統深度定製 Kong 或 OpenResty,主要是出於工程性方面的考慮。舉個例子:假如我們有多個不同業務線,鑑權方式五花八門,都是與業務多少有點相關的。這時如果把鑑權在網關實現,就需要維護大量的 Lua 腳本,引入一個新的複雜技術棧是一個成本不低的事情。

Spring Cloud Gateway/Zuul 2 對於 Java 技術棧來說比較方便,可以依賴業務系統的一些通用的類庫。Lua 不方便,不光是語言的問題,更是複用基礎設施的問題。另外,對於網關係統來說,性能不會差一個數量級,問題不大,多加 2 臺機器就可以 “搞定”。

從測試的結果來看,如果後端 API 服務的延遲都較低(例如 2ms 級別),直連的吞吐量假如是 100QPS,Kong 可以達到 60QPS,OpenResty 是 50QPS,Zuul 2 和 Spring CloudGateway 大概是 35QPS,如果服務本身的延遲(latency)大一點,那麼這些差距會逐步縮小。

目前來看 Zuul 2 的 “坑” 還是比較多的:

(1)剛出不久,不成熟,沒什麼文檔,還沒有太多的實際應用案例。

(2)高併發時出錯率較高,1000 併發時我們的測試場景有近 50% 的出錯率。

簡單使用或輕度定製業務網關係統,目前建議使用 Spring CloudGateway 作爲基礎骨架。

2. 各類網關的 Demo 與測試

以上測試用到的模擬服務和網關 Demo 代碼,大部分可以在這裏找到:

https://github.com/ kimmking/atlantis。

我們使用 Vert.x 實現了一個簡單網關,性能跟 Zuul 2 和 Spring Cloud Gateway 差不多。另外也簡單模擬了一個 Node.js 做的網關 Demo,加了 keep-alive 和 pool,Demo 的性能測試結果大概是直連的 1/9,也就是 Spring Cloud Gateway 或 Zuul 2 的 1/4 左右。

百億流量交易系統 API 網關設計

百億流量交易系統 API 網關的現狀和麪臨問題

1. 百億流量系統面對的業務現狀

百億流量系統面對的業務現狀如圖 7-11 所示。

 圖 7-11

我們目前面臨的現狀是日常十幾萬的併發在線長連接數(不算短連接),每天長連接總數爲 3000 萬 +,每天 API 的調用次數超過 100 億次,每天交易訂單數爲 1.5 億個。

在這種情況下,API 網關設計的一個重要目標就是:如何藉助 API 網關爲各類客戶提供精準、專業、個性化的服務,保障客戶實時地獲得業務系統的數據和業務能力。

2. 網關係統與其他系統的關係

某交易系統的 API 網關係統與其他系統的關係大致如圖 7-12 所示。

圖 7-12

3. 網關係統典型的應用場景

我們的 API 網關係統爲 Web 端、移動 App 端客戶提供服務,也爲大量 API 客戶提供 API 調用服務,同時支持 REST API 和 WebSocket 協議。

作爲實時交易系統的前置系統,必須精準及時爲客戶提供最新的行情和交易信息。一旦出現數據的延遲或錯誤,都會給客戶造成無法挽回的損失。

另外針對不同的客戶和渠道,網關係統需要提供不同的安全、驗證、流控、緩存策略,同時可以隨時聚合不同視角的數據進行預處理,保障系統的穩定可靠和數據的實時精確。

4. 交易系統 API 的特點

作爲一個全球性的交易系統,我們的 API 特點總結如下。

5. 交易系統 API 網關面臨的問題

問題 1:流量不斷增加。

如何合理控制流量,如何應對突發流量,如何最大限度地保障系統穩定,都是重要的問題。特別是網關作爲一個直接面對客戶的系統,出現的任何問題都會放大百倍。很多千奇百怪的從來沒人遇到的問題隨時都可能出現。

問題 2:網關係統越來越複雜。

現有的業務網關經過多年發展,裏面有大量的業務嵌入,並且存在多個不同的業務網關,相互之間沒有任何關係,也沒有沉澱出基礎設施。

同時技術債務太多,系統裏硬編碼實現了全局性網關策略及很多業務規則,導致維護成本較大。

問題 3:API 網關管理比較困難。

海量併發下 API 的監控指標設計和數據的收集也是一個不小的問題。7×24 小時運行的技術支持也導致維護成本較高。

問題 4:選擇推送還是拉取。

使用短連接還是長連接,REST API 還是 WebSocket?業務渠道較多(多個不同產品線的 Web、App、API 等形成十幾個不同的渠道),導致用戶的使用行爲難以控制。

業務網關的設計與最佳實踐

1. API 網關 1.0

我們的 API 網關 1.0 版本是多年前開發的,是直接使用 OpenResty 定製的,全局的安全測試、流量的路由轉發策略、針對不同級別的限流等都是直接用 Lua 腳本實現。

這樣就導致在經歷了業務飛速發展以後,系統裏存在非常多的相同功能或不同功能的 Lua 腳本,每次上線或維護都需要找到受影響的其中幾個或幾十個 Lua 腳本,進行策略調整,非常不方便,策略控制的粒度也不夠細。

2. API 網關 2.0

在區分了流量網關和業務網關以後,2017 年開始實現了流量網關和業務網關的分離,流量網關繼續使用 OpenResty 定製,只保留少量全局性、不經常改動的配置功能和對應的 Lua 腳本。

業務網關使用 Vert.x 實現的 Java 系統,部署在流量網關和後端業務服務系統之間,利用 Vert.x 的響應式編程能力和異步非阻塞 I/O 能力、分佈式部署的擴展能力,初步解決了問題 1 和問題 2,如圖 7-13 所示。

圖 7-13

Vert.x 是一個基於事件驅動和異步非阻塞 I/O、運行於 JVM 上的框架,如圖 7-14 所示。在 Vert.x 裏,Verticle 是最基礎的開發和部署單元,不同的 Vert.x 可以通過 Event Bus 傳遞數據,進而方便地實現高併發性能的網絡程序。關於 Vert.x 原理的分析可以參考阿里架構師宿何的 blog:

https://www.sczyh30.com/tags/Vert-x/。

圖 7-14

Vert.x 同時很好地支持了 WebSocket 協議,所以可以方便地實現支持 REST API 和 WebSocket、完全異步的網關係統,如圖 7-15 所示。

圖 7-15

一個高性能的 API 網關係統,緩存是必不可少的部分。無論分發冷熱數據,降低對業務系統的壓力,還是作爲中間數據源,爲服務聚合提供高效可複用的業務數據,緩存都發揮了巨大作用。

3. API 網關的日常監控

我們使用多種工具對 API 進行監控和管理,包括全鏈路訪問跟蹤、連接數統計分析、全世界重要國家和城市的波測訪問統計。網關技術團隊每時每刻都關注着數據的變化趨勢。各個業務系統研發團隊每天安排專人關注自己系統的 API 性能(吞吐量和延遲),推進性能問題解決和持續優化。這就初步解決了問題 3。

4. 推薦外部客戶使用 WebSocket 和 API SDK

由於外部客戶需要自己通過 API 網關調用 API 服務來集成業務服務能力到自己的系統。各個客戶的技術能力和系統處理能力有較大差異,使用行爲也不同。對於不斷髮展變動的交易業務數據,客戶調用 API 頻率太低會影響數據實時性,調用頻率太高則可能會浪費雙方的系統資源。同時利用 WebSocket 的消息推送特點,我們可以在網關係統控制客戶接收消息的頻率、單個用戶的連接數量等,隨時根據業務系統的情況動態進行策略調整。綜合考慮,WebSocket 是一個比 REST API 更加實時可靠、更加易於管理的方式。另外對於習慣使用 REST API 的客戶,我們也通過將各種常見使用場景封裝成多種不同語言的 API SDK(包括 Java/C++/C#/Python),進而統一用戶的 API 調用方式和行爲。在研發、產品、運營各方的配合下,逐步協助客戶使用 WebSocket 協議和 API SDK,基本解決了問題 4。

5. API 網關的性能優化

API 網關係統作爲 API 服務的統一接入點,爲了給用戶提供最優質的用戶體驗,必須長期做性能優化工作。不僅 API 網關自己做優化,同時可以根據監控情況,時刻發現各業務系統的 API 服務能力,以此爲出發點,推動各個業務系統不斷優化 API 性能。

舉一個具體的例子,某個網關係統連接經常強烈抖動(如圖 7-16 所示),嚴重影響系統的穩定性、浪費系統資源,經過排除發現:

(1)有爬蟲 IP 不斷爬取我們的交易數據,而且這些 IP 所在網段都沒有在平臺產生任何實際交易,最高單爬蟲 IP 的每日新建連接近 100 萬次,平均每秒十幾次。

(2)有部分 API 客戶的程序存在 bug,而且處理速度有限,不斷地重複 “斷開並重新連接”,再嘗試重新對 API 數據進行處理,嚴重影響了客戶的用戶體驗。

針對如上分析,我們採取瞭如下處理方式:

(1)對於每天認定的爬蟲 IP,加入黑名單,直接在流量網關限制其訪問我們的 API 網關。

(2)對於存在 bug 的 API 客戶,協助對方進行問題定位和 bug 修復,增強客戶使用信心。

(3)對於處理速度和技術能力有限的客戶,基於定製的 WebSocket 服務,使用滑動時間窗口算法,在業務數據變化非常大時,對分發的消息進行批量優化。

圖 7-16

(4)對於未登錄和識別身份的 API 調用,流量網關實現全局的流控策略,增加緩存時間和限制調用次數,保障系統穩定。

(5)業務網關根據 API 服務的重要等級和客戶的分類,進一步細化和實時控制網關策略,最大限度地保障核心業務和客戶的使用。

從監控圖表可以看到,優化之後的效果非常明顯,系統穩定,連接數平穩。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s?__biz=MzIxMzEzMjM5NQ==&mid=2651032682&idx=1&sn=6fa8158e697246e7fb2afbf0be3597ac&chksm=8c4c596ebb3bd0785e9bc6b6bd515b325651b8fe06dbdb162bdc19a0e5cfb54464df63e5546d&scene=178&cur_album_id=1343963749467717633#rd