百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)-創(chuàng)新互聯(lián)

本文從百億流量交易系統(tǒng)微服務(wù)網(wǎng)關(guān)(API Gateway)的現(xiàn)狀和面臨的問題出發(fā),闡述微服務(wù)架構(gòu)與 API 網(wǎng)關(guān)的關(guān)系,理順流量網(wǎng)關(guān)與業(yè)務(wù)網(wǎng)關(guān)的脈絡(luò),分享API網(wǎng)關(guān)知識與經(jīng)驗(yàn)。

創(chuàng)新互聯(lián)公司成立于2013年,我們提供高端成都網(wǎng)站建設(shè)公司、成都網(wǎng)站制作成都網(wǎng)站設(shè)計(jì)、網(wǎng)站定制、網(wǎng)絡(luò)營銷推廣小程序設(shè)計(jì)、微信公眾號開發(fā)、網(wǎng)站推廣服務(wù),提供專業(yè)營銷思路、內(nèi)容策劃、視覺設(shè)計(jì)、程序開發(fā)來完成項(xiàng)目落地,為成都高空作業(yè)車租賃企業(yè)提供源源不斷的流量和訂單咨詢。

API網(wǎng)關(guān)概述

“計(jì)算機(jī)科學(xué)領(lǐng)域的任何問題都可以通過增加一個(gè)間接的中間層來解決?!?/p>

——David Wheeler

  • 請求接入:作為所有API接口服務(wù)請求的接入點(diǎn),管理所有的接入請求。

  • 業(yè)務(wù)聚合:作為所有后端業(yè)務(wù)服務(wù)的聚合點(diǎn),所有的業(yè)務(wù)服務(wù)都可以在這里被調(diào)用。

  • 中介策略:實(shí)現(xiàn)安全、驗(yàn)證、路由、過濾、流控、緩存等策略,進(jìn)行一些必要的中介處理。

  • 統(tǒng)一管理:提供配置管理工具,對所有API服務(wù)的調(diào)用生命周期和相應(yīng)的中介策略進(jìn)行統(tǒng)一管理。

  • 3. API網(wǎng)關(guān)的關(guān)注點(diǎn)

    API網(wǎng)關(guān)并不是一個(gè)典型的業(yè)務(wù)系統(tǒng),而是一個(gè)為了讓業(yè)務(wù)系統(tǒng)更專注于業(yè)務(wù)服務(wù)本身,給API服務(wù)提供更多附加能力的一個(gè)中間層。

    在設(shè)計(jì)和實(shí)現(xiàn)API網(wǎng)關(guān)時(shí),需要考慮兩個(gè)目標(biāo):

    (1)開發(fā)維護(hù)簡單,節(jié)約人力成本和維護(hù)成本。即應(yīng)選擇成熟的簡單可維護(hù)的技術(shù)體系。

    (2)高性能,節(jié)約設(shè)備成本,提高系統(tǒng)吞吐能力。要求我們需要針對API網(wǎng)關(guān)的特點(diǎn)進(jìn)行一些特定的設(shè)計(jì)和權(quán)衡。

    當(dāng)并發(fā)量小的時(shí)候,這些都不是問題。一旦系統(tǒng)的API訪問量非常大,這些都會(huì)成為關(guān)鍵的問題。

    海量并發(fā)的API網(wǎng)關(guān)最重要的三個(gè)關(guān)注點(diǎn):

    (1)保持大規(guī)模的inbound請求接入能力(長短連接),比如基于Netty實(shí)現(xiàn)。

    (2)大限度地復(fù)用outbound的HTTP連接能力,比如基于HttpClient4的異步HttpClient實(shí)現(xiàn)。

    (3)方便靈活地實(shí)現(xiàn)安全、驗(yàn)證、過濾、聚合、限流、監(jiān)控等各種策略。

    API網(wǎng)關(guān)的分類與技術(shù)分析

    1. API網(wǎng)關(guān)的分類

    如果對上述的目標(biāo)和關(guān)注點(diǎn)進(jìn)行更深入的思考,那么所有需要考慮的問題和功能可以分為兩類。

    • 一類是全局性的,跟具體的后端業(yè)務(wù)系統(tǒng)和服務(wù)完全無關(guān)的部分,比如安全策略、全局性流控策略、流量分發(fā)策略等。

    • 一類是針對具體的后端業(yè)務(wù)系統(tǒng),或者是服務(wù)和業(yè)務(wù)有一定關(guān)聯(lián)性的部分,并且一般被直接部署在業(yè)務(wù)服務(wù)的前面。

    隨著互聯(lián)網(wǎng)的復(fù)雜業(yè)務(wù)系統(tǒng)的發(fā)展,這兩類功能集合逐漸形成了現(xiàn)在常見的兩種網(wǎng)關(guān)系統(tǒng):流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān),如圖7-5所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-5

    2. 流量網(wǎng)關(guān)與WAF

    我們定義全局性的、跟具體的后端業(yè)務(wù)系統(tǒng)和服務(wù)完全無關(guān)的策略網(wǎng)關(guān),即為流量網(wǎng)關(guān)。這樣流量網(wǎng)關(guān)關(guān)注全局流量的穩(wěn)定與安全,比如防止各類SQL注入、黑白名單控制、接入請求到業(yè)務(wù)系統(tǒng)的負(fù)載均衡等,通常有如下通用性的具體功能:

    • 全局性流控;

    • 日志統(tǒng)計(jì);

    • 防止SQL注入;

    • 防止Web攻擊;

    • 屏蔽工具掃描;

    • 黑白名單控制。

    通過這個(gè)功能清單,我們可以發(fā)現(xiàn),流量網(wǎng)關(guān)的功能跟Web應(yīng)用防火墻(WAF)非常類似。WAF一般是基于Nginx/OpenResty的ngx_lua模塊開發(fā)的Web應(yīng)用防火墻。

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

    一般的WAF具有如下功能:

    • 防止SQL注入、部分溢出、fuzzing測試、XSS/SSRF等Web攻擊;

    • 防止Apache Bench之類壓力測試工具的攻擊;

    • 屏蔽常見的掃描黑客工具,比如掃描器;

    • 禁止圖片附件類目錄執(zhí)行權(quán)限、防止webshell上傳;

    • 支持IP白名單和黑名單功能,直接拒絕黑名單的IP訪問;

    • 支持URL白名單,定義不需要過濾的URL;

    • 支持User-Agent的過濾、支持CC攻擊防護(hù)、限制單個(gè)URL指定時(shí)間的訪問次數(shù);

    • 支持支持Cookie過濾,URL與URL參數(shù)過濾;

    • 支持日志記錄,將所有拒絕的操作記錄到日志中。

    以上WAF的內(nèi)容主要參考如下兩個(gè)項(xiàng)目:

    • https://github.com/unixhot/waf;

    • https://github.com/loveshell/ngx_lua_waf。

    流量網(wǎng)關(guān)的開源實(shí)例還可以參考著名的開源項(xiàng)目Kong(基于OpenResty)。

    3. 業(yè)務(wù)網(wǎng)關(guān)

    我們定義針對具體的后端業(yè)務(wù)系統(tǒng),或者是服務(wù)和業(yè)務(wù)有一定關(guān)聯(lián)性的策略網(wǎng)關(guān),即為業(yè)務(wù)網(wǎng)關(guān)。比如,針對某個(gè)系統(tǒng)、某個(gè)服務(wù)或某個(gè)用戶分類的流控策略,針對某一類服務(wù)的緩存策略,針對某個(gè)具體系統(tǒng)的權(quán)限驗(yàn)證方式,針對某些用戶條件判斷的請求過濾,針對具體幾個(gè)相關(guān)API的數(shù)據(jù)聚合封裝,等等。

    業(yè)務(wù)網(wǎng)關(guān)一般部署在流量網(wǎng)關(guān)之后、業(yè)務(wù)系統(tǒng)之前,比流量網(wǎng)關(guān)更靠近業(yè)務(wù)系統(tǒng)。我們大部分情況下說的API網(wǎng)關(guān),狹義上指的是業(yè)務(wù)網(wǎng)關(guān)。如果系統(tǒng)的規(guī)模不大,我們也會(huì)將兩者合二為一,使用一個(gè)網(wǎng)關(guān)來處理所有的工作。

    開源網(wǎng)關(guān)的分析與調(diào)研

    常見的開源網(wǎng)關(guān)介紹

    常見的開源網(wǎng)關(guān)如圖7-6所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-6

    目前常見的開源網(wǎng)關(guān)大致上按照語言分類有如下幾類。

    • Nginx+Lua:Open Resty、Kong、Orange、Abtesting Gateway等;

    • Java:Zuul/Zuul 2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul等;

    • Go:Janus、fagongzi、Grpc-Gateway;

    • .NET:Ocelot;

    • Node.js:Express Gateway、MicroGateway。

    按照使用范圍、成熟度等來劃分,主流的有4個(gè):OpenResty、Kong、Zuul/Zuul 2、Spring Cloud Gateway,此外fagongzi API網(wǎng)關(guān)最近也獲得不少關(guān)注。

    1. Nginx+Lua網(wǎng)關(guān)

    OpenResty

    項(xiàng)目地址:http://openresty.org/

    OpenResty基于Nginx,集成了Lua語言和Lua的各種工具庫、可用的第三方模塊,這樣我們就在Nginx既有的高效HTTP處理的基礎(chǔ)上,同時(shí)獲得了Lua提供的動(dòng)態(tài)擴(kuò)展能力。因此,我們可以做出各種符合我們需要的網(wǎng)關(guān)策略的Lua腳本,以其為基礎(chǔ)實(shí)現(xiàn)網(wǎng)關(guān)系統(tǒng)。

    Kong

    項(xiàng)目地址:https://konghq.com/與https://github.com/kong/kong

    Kong基于OpenResty,是一個(gè)云原生、快速、可擴(kuò)展、分布式的微服務(wù)抽象層(MicroserviceAbstraction Layer),也叫API網(wǎng)關(guān)(API Gateway),在Service Mesh里也叫API中間件(API Middleware)。

    Kong開源于2015年,核心價(jià)值在于其高性能和擴(kuò)展性。從全球5000強(qiáng)的組織統(tǒng)計(jì)數(shù)據(jù)來看,Kong是現(xiàn)在依然在維護(hù)的、在生產(chǎn)環(huán)境使用最廣泛的網(wǎng)關(guān)。

    核心優(yōu)勢如下。

    • 可擴(kuò)展:可以方便地通過添加節(jié)點(diǎn)實(shí)現(xiàn)水平擴(kuò)展,這意味著可以在很低的延遲下支持很大的系統(tǒng)負(fù)載。

    • 模塊化:可以通過添加新的插件來擴(kuò)展Kong的能力,這些插件可以通過RESTful Admin API來安裝和配置。

    • 在任何基礎(chǔ)架構(gòu)上運(yùn)行:Kong在任何地方都能運(yùn)行,比如在云或混合環(huán)境中部署Kong,或者單個(gè)/全球的數(shù)據(jù)中心。

    ABTestingGateway

    項(xiàng)目地址:https://github.com/CNSRE/ABTestingGateway

    ABTestingGateway是一個(gè)可以動(dòng)態(tài)設(shè)置分流策略的網(wǎng)關(guān),關(guān)注與灰度發(fā)布相關(guān)的領(lǐng)域,基于Nginx和ngx-lua開發(fā),使用Redis作為分流策略數(shù)據(jù)庫,可以實(shí)現(xiàn)動(dòng)態(tài)調(diào)度功能。

    ABTestingGateway是新浪微博內(nèi)部的動(dòng)態(tài)路由系統(tǒng)dygateway的一部分,目前已經(jīng)開源。在以往的基于Nginx實(shí)現(xiàn)的灰度系統(tǒng)中,分流邏輯往往通過rewrite階段的if和rewrite指令等實(shí)現(xiàn),優(yōu)點(diǎn)是性能較高,缺點(diǎn)是功能受限、容易出錯(cuò),以及轉(zhuǎn)發(fā)規(guī)則固定,只能靜態(tài)分流。ABTestingGateway則采用 ngx-lua,通過啟用lua-shared-dict和lua-resty-lock作為系統(tǒng)緩存和緩存鎖,系統(tǒng)獲得了較為接近原生Nginx轉(zhuǎn)發(fā)的性能。

    功能特性如下。

    • 支持多種分流方式,目前包括iprange、uidrange、uid尾數(shù)和指定uid分流;

    • 支持多級分流,動(dòng)態(tài)設(shè)置分流策略,即時(shí)生效,無須重啟;

    • 可擴(kuò)展性,提供了開發(fā)框架,開發(fā)者可以靈活添加新的分流方式,實(shí)現(xiàn)二次開發(fā);

    • 高性能,壓測數(shù)據(jù)接近原生Nginx轉(zhuǎn)發(fā);

    • 灰度系統(tǒng)配置寫在Nginx配置文件中,方便管理員配置;

    • 適用于多種場景:灰度發(fā)布、AB測試和負(fù)載均衡等。

    據(jù)了解,美團(tuán)網(wǎng)內(nèi)部的Oceanus也是基于Nginx和ngx-lua擴(kuò)展實(shí)現(xiàn)的,主要提供服務(wù)注冊與發(fā)現(xiàn)、動(dòng)態(tài)負(fù)載均衡、可視化管理、定制化路由、安全反扒、Session ID復(fù)用、熔斷降級、一鍵截流和性能統(tǒng)計(jì)等功能。

    2. 基于Java語言的網(wǎng)關(guān)

    Zuul/Zuul2

    項(xiàng)目地址:https://github.com/Netflix/zuul

    Zuul是Netflix開源的API網(wǎng)關(guān)系統(tǒng),它的主要設(shè)計(jì)目標(biāo)是動(dòng)態(tài)路由、監(jiān)控、彈性和安全。

    Zuul的內(nèi)部原理可以簡單看作很多不同功能filter的集合(作為對比,ESB也可以簡單被看作管道和過濾器的集合)。這些過濾器(filter)可以使用Groovy或其他基于JVM的腳本編寫(當(dāng)然Java也可以編寫),放置在指定的位置,然后可以被Zuul Server輪詢,發(fā)現(xiàn)變動(dòng)后動(dòng)態(tài)加載并實(shí)時(shí)生效。Zuul目前有1.x和2.x兩個(gè)版本,這兩個(gè)版本的差別很大。

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

    在Zuul 1.x里,F(xiàn)ilter的種類和處理流程如圖7-7所示,最主要的就是pre、routing、post這三種過濾器,分別作用于調(diào)用業(yè)務(wù)服務(wù)API之前的請求處理、直接響應(yīng)、調(diào)用業(yè)務(wù)服務(wù)API之后的響應(yīng)處理。

    Zuul 2.x大的改進(jìn)就是基于Netty Server實(shí)現(xiàn)了異步I/O來接入請求,同時(shí)基于Netty Client實(shí)現(xiàn)了到后端業(yè)務(wù)服務(wù)API的請求。這樣就可以實(shí)現(xiàn)更高的性能、更低的延遲。此外也調(diào)整了Filter類型,將原來的三個(gè)核心Filter顯式命名為Inbound Filter、Endpoint Filter和Outbound Filter,如圖7-8所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-7

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-8

    Zuul 2.x的核心功能:服務(wù)發(fā)現(xiàn)、負(fù)載均衡、連接池、狀態(tài)分類、重試、請求憑證、HTTP/2、TLS、代理協(xié)議、GZip、WebSocket。

    SpringCloud Gateway

    項(xiàng)目地址:https://github.com/spring-cloud/spring-cloud-gateway/

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

    Spring Cloud Gateway可以看作一個(gè)Zuul 1.x的升級版和代替品,比Zuul 2更早地使用Netty實(shí)現(xiàn)異步I/O,從而實(shí)現(xiàn)了一個(gè)簡單、比Zuul 1.x更高效的、與Spring Cloud緊密配合的API網(wǎng)關(guān)。

    Spring Cloud Gateway里明確地區(qū)分了Router和Filter,內(nèi)置了非常多的開箱即用功能,并且都可以通過Spring Boot配置或手工編碼鏈?zhǔn)秸{(diào)用來使用。

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

    核心特性:

    • 通過請求參數(shù)匹配路由;

    • 通過斷言和過濾器實(shí)現(xiàn)路由;

    • 與Hystrix熔斷集成;

    • 與Spring Cloud DiscoveryClient集成;

    • 非常方便地實(shí)現(xiàn)斷言和過濾器;

    • 請求限流;

    • 路徑重寫。

    graviteeGateway

    項(xiàng)目地址:https://gravitee.io/與https://github.com/gravitee-io/gravitee-gateway

    KaazingWebSocket Gateway

    項(xiàng)目地址:

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

    Kaazing WebSocket Gateway是一個(gè)專門針對和處理WebSocket的網(wǎng)關(guān),宣稱提供世界一流的企業(yè)級WebSocket服務(wù)能力。具體如下特性:

    • 標(biāo)準(zhǔn)WebSocket支持,支持全雙工的雙向數(shù)據(jù)投遞;

    • 線性擴(kuò)展,無狀態(tài)架構(gòu)意味著可以部署更多機(jī)器來擴(kuò)展服務(wù)能力;

    • 驗(yàn)證,鑒權(quán),單點(diǎn)登錄支持,跨域訪問控制;

    • SSL/TLS加密支持;

    • WebSocket keepalive和TCP半開半關(guān)探測;

    • 通過負(fù)載均衡和集群實(shí)現(xiàn)高可用;

    • Docker支持;

    • JMS/AMQP等支持;

    • IP白名單;

    • 自動(dòng)重連和消息可靠接受保證;

    • Fanout處理策略;

    • 實(shí)時(shí)緩存等。

    Dromara soul

    項(xiàng)目地址:https://github.com/Dromara/soul。

    Soul是一個(gè)異步的、高性能的、跨語言的、響應(yīng)式的API網(wǎng)關(guān),提供了統(tǒng)一的HTTP訪問。

    • 支持各種語言,無縫集成Dubbo和SpringCloud;

    • 豐富的插件支持鑒權(quán)、限流、熔斷、防火墻等;

    • 網(wǎng)關(guān)多種規(guī)則動(dòng)態(tài)配置,支持各種策略配置;

    • 插件熱插拔,易擴(kuò)展;

    • 支持集群部署,支持A/B Test。

    3. 基于Go語言的網(wǎng)關(guān)

    fagongzi

    項(xiàng)目地址:https://github.com/fagongzi/gateway

    fagongzi Gateway是一個(gè)Go實(shí)現(xiàn)的功能全面的API網(wǎng)關(guān),自帶了一個(gè)Rails實(shí)現(xiàn)的Web UI管理界面。

    功能特性:流量控制、熔斷、負(fù)載均衡、服務(wù)發(fā)現(xiàn)、插件機(jī)制、路由(分流,復(fù)制流量)、API聚合、API參數(shù)校驗(yàn)、API訪問控制(黑白名單)、API默認(rèn)返回值、API定制返回值、API結(jié)果Cache、JWT認(rèn)證、API Metric導(dǎo)入Prometheus、API失敗重試、后端Server的健康檢查、開放管理API(gRPC、RESTful)、支持WebSocket協(xié)議。

    Janus

    項(xiàng)目地址:https://github.com/hellofresh/janus

    Janus是一個(gè)輕量級的API網(wǎng)關(guān)和管理平臺(tái),能實(shí)現(xiàn)控制誰、什么時(shí)候、如何訪問這些REST API,同時(shí)它也記錄了所有的訪問交互細(xì)節(jié)和錯(cuò)誤。使用Go實(shí)現(xiàn)API網(wǎng)關(guān)的一個(gè)好處在于,一般只需要一個(gè)單獨(dú)的二進(jìn)制文件即可運(yùn)行,沒有復(fù)雜的依賴關(guān)系。功能特性:

    • 熱加載配置,不需要重啟網(wǎng)關(guān)進(jìn)程;

    • HTTP連接的優(yōu)雅關(guān)閉;

    • 支持OpenTracing,從而可以進(jìn)行分布式跟蹤;

    • 支持HTTP/2;

    • 可以針對每一個(gè)API實(shí)現(xiàn)斷路器;

    • 重試機(jī)制;

    • 流控,可以針對每一個(gè)用戶或key;

    • CORS過濾,可以針對具體的API;

    • 多種開箱即用的驗(yàn)證協(xié)議支持,比如JWT、OAuth 2.0和Basic Auth;

    • Docker Image支持。

    4. .NET

    Ocelot

    項(xiàng)目地址:https://github.com/ThreeMammals/Ocelot

    功能特性:路由、請求聚合、服務(wù)發(fā)現(xiàn)(基于Consul或Eureka)、服務(wù)Fabric、WebSockets、驗(yàn)證與鑒權(quán)、流控、緩存、重試策略與QoS、負(fù)載均衡、日志與跟蹤、請求頭、Query字符串轉(zhuǎn)換、自定義的中間處理、配置和管理REST API。

    5. Node.js

    Express Gateway

    項(xiàng)目地址:

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

    Express Gateway是一個(gè)基于Node.js開發(fā),使用Express和Express中間件實(shí)現(xiàn)的REST API網(wǎng)關(guān)。

    功能特性:

    • 動(dòng)態(tài)中心化配置;

    • API消費(fèi)者和憑證管理;

    • 插件機(jī)制;

    • 分布式數(shù)據(jù)存儲(chǔ);

    • 命令行工具CLI。

    MicroGateway

    項(xiàng)目地址:

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

    StrongLoop是IBM的一個(gè)子公司,MicroGateway網(wǎng)關(guān)基于Node.js/Express和Nginx構(gòu)建,作為IBM API Connect,同時(shí)也是IBM云生態(tài)的一部分。MicroGateway是一個(gè)聚焦于開發(fā)者,可擴(kuò)展的網(wǎng)關(guān)框架,它可以增強(qiáng)我們對微服務(wù)和API的訪問能力。

    核心特性:

    • 安全和控制,基于Swagger(OpenAPI)規(guī)范;

    • 內(nèi)置了多種網(wǎng)關(guān)策略,API Key驗(yàn)證、流控、OAuth 2.0、JavaScript腳本支持;

    • 使用Swagger擴(kuò)展(API Assembly)實(shí)現(xiàn)網(wǎng)關(guān)策略(安全、路由、集成等);

    • 方便地自定義網(wǎng)關(guān)策略。

    此外,MicroGateway還有幾個(gè)特性:

    • 通過集成Swagger,實(shí)現(xiàn)基于Swagger API定義的驗(yàn)證能力;

    • 使用datastore來保持需要處理的API數(shù)據(jù)模型;

    • 使用一個(gè)流式引擎來處理多種策略,使API設(shè)計(jì)者可以更好地控制API的生命周期。

    核心架構(gòu)如圖7-9所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-9

    四大開源網(wǎng)關(guān)的對比分析

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

    各項(xiàng)指標(biāo)對比如表7-1所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    以限流功能為例:

    • Spring Cloud Gateway目前提供了基于Redis的Ratelimiter實(shí)現(xiàn),使用的算法是令牌桶算法,通過YAML文件進(jìn)行配置;

    • Zuul2可以通過配置文件配置集群限流和單服務(wù)器限流,也可通過Filter實(shí)現(xiàn)限流擴(kuò)展;

    • OpenResty可以使用resty.limit.count、resty.limit.conn、resty.limit.req來實(shí)現(xiàn)限流功能,可實(shí)現(xiàn)漏桶或令牌通算法;

    • Kong擁有基礎(chǔ)限流組件,可在基礎(chǔ)組件源代碼基礎(chǔ)上進(jìn)行Lua開發(fā)。

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

    2. OpenResty/Kong/Zuul 2/SpringCloudGateway性能測試對比

    分別使用3臺(tái)4Core、16GB內(nèi)存的機(jī)器,作為API服務(wù)提供者、Gateway、壓力機(jī),使用wrk作為性能測試工具,對OpenResty/Kong/Zuul 2/SpringCloud Gateway進(jìn)行簡單小報(bào)文下的性能測試,如圖7-10所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-10

    圖中縱坐標(biāo)軸是QPS,橫軸是一個(gè)Gateway的數(shù)據(jù),每根線是一個(gè)場景下的不同網(wǎng)關(guān)數(shù)據(jù),測試結(jié)論如下:

    • 實(shí)測情況是性能SCG~Zuul 2 << OpenResty~< Kong << Direct(直連);

    • Spring Cloud Gateway、Zuul 2的性能差不多,大概是直連的40%;

    • OpenResty、Kong的性能差不多,大概是直連的60%~70%;

    • 大并發(fā)下,例如模擬200并發(fā)用戶、1000并發(fā)用戶時(shí),Zuul 2會(huì)有很大概率返回出錯(cuò)。

    開源網(wǎng)關(guān)的技術(shù)總結(jié)

    1. 開源網(wǎng)關(guān)的測試分析

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

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

    Kong的性能非常不錯(cuò),非常適合做流量網(wǎng)關(guān),并且對于service、route、upstream、consumer、plugins的抽象,也是自研網(wǎng)關(guān)值得借鑒的。

    對于復(fù)雜系統(tǒng),不建議業(yè)務(wù)網(wǎng)關(guān)用Kong,或者更明確地說是不建議在Java技術(shù)棧的系統(tǒng)深度定制Kong或OpenResty,主要是出于工程性方面的考慮。舉個(gè)例子:假如我們有多個(gè)不同業(yè)務(wù)線,鑒權(quán)方式五花八門,都是與業(yè)務(wù)多少有點(diǎn)相關(guān)的。這時(shí)如果把鑒權(quán)在網(wǎng)關(guān)實(shí)現(xiàn),就需要維護(hù)大量的Lua腳本,引入一個(gè)新的復(fù)雜技術(shù)棧是一個(gè)成本不低的事情。

    Spring Cloud Gateway/Zuul 2對于Java技術(shù)棧來說比較方便,可以依賴業(yè)務(wù)系統(tǒng)的一些通用的類庫。Lua不方便,不光是語言的問題,更是復(fù)用基礎(chǔ)設(shè)施的問題。另外,對于網(wǎng)關(guān)系統(tǒng)來說,性能不會(huì)差一個(gè)數(shù)量級,問題不大,多加2臺(tái)機(jī)器就可以“搞定”。

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

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

    (1)剛出不久,不成熟,沒什么文檔,還沒有太多的實(shí)際應(yīng)用案例。

    (2)高并發(fā)時(shí)出錯(cuò)率較高,1000并發(fā)時(shí)我們的測試場景有近50%的出錯(cuò)率。

    簡單使用或輕度定制業(yè)務(wù)網(wǎng)關(guān)系統(tǒng),目前建議使用Spring CloudGateway作為基礎(chǔ)骨架。

    2. 各類網(wǎng)關(guān)的Demo與測試

    以上測試用到的模擬服務(wù)和網(wǎng)關(guān)Demo代碼,大部分可以在這里找到:

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

    我們使用Vert.x實(shí)現(xiàn)了一個(gè)簡單網(wǎng)關(guān),性能跟Zuul 2和Spring Cloud Gateway差不多。另外也簡單模擬了一個(gè)Node.js做的網(wǎng)關(guān)Demo,加了keep-alive和pool,Demo的性能測試結(jié)果大概是直連的1/9,也就是Spring Cloud Gateway或Zuul 2的1/4左右。

    百億流量交易系統(tǒng)API網(wǎng)關(guān)設(shè)計(jì)

    百億流量交易系統(tǒng)API網(wǎng)關(guān)的現(xiàn)狀和面臨問題

    1. 百億流量系統(tǒng)面對的業(yè)務(wù)現(xiàn)狀

    百億流量系統(tǒng)面對的業(yè)務(wù)現(xiàn)狀如圖7-11所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

     圖7-11

    我們目前面臨的現(xiàn)狀是日常十幾萬的并發(fā)在線長連接數(shù)(不算短連接),每天長連接總數(shù)為3000萬+,每天API的調(diào)用次數(shù)超過100億次,每天交易訂單數(shù)為1.5億個(gè)。

    在這種情況下,API網(wǎng)關(guān)設(shè)計(jì)的一個(gè)重要目標(biāo)就是:如何借助API網(wǎng)關(guān)為各類客戶提供精準(zhǔn)、專業(yè)、個(gè)性化的服務(wù),保障客戶實(shí)時(shí)地獲得業(yè)務(wù)系統(tǒng)的數(shù)據(jù)和業(yè)務(wù)能力。

    2. 網(wǎng)關(guān)系統(tǒng)與其他系統(tǒng)的關(guān)系

    某交易系統(tǒng)的API網(wǎng)關(guān)系統(tǒng)與其他系統(tǒng)的關(guān)系大致如圖7-12所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-12

    3. 網(wǎng)關(guān)系統(tǒng)典型的應(yīng)用場景

    我們的API網(wǎng)關(guān)系統(tǒng)為Web端、移動(dòng)App端客戶提供服務(wù),也為大量API客戶提供API調(diào)用服務(wù),同時(shí)支持REST API和WebSocket協(xié)議。

    作為實(shí)時(shí)交易系統(tǒng)的前置系統(tǒng),必須精準(zhǔn)及時(shí)為客戶提供最新的行情和交易信息。一旦出現(xiàn)數(shù)據(jù)的延遲或錯(cuò)誤,都會(huì)給客戶造成無法挽回的損失。

    另外針對不同的客戶和渠道,網(wǎng)關(guān)系統(tǒng)需要提供不同的安全、驗(yàn)證、流控、緩存策略,同時(shí)可以隨時(shí)聚合不同視角的數(shù)據(jù)進(jìn)行預(yù)處理,保障系統(tǒng)的穩(wěn)定可靠和數(shù)據(jù)的實(shí)時(shí)精確。

    4. 交易系統(tǒng)API的特點(diǎn)

    作為一個(gè)全球性的交易系統(tǒng),我們的API特點(diǎn)總結(jié)如下。

    • 訪問非常集中:最核心的一組API占據(jù)了訪問量的一半以上;

    • 訪問非常頻繁:QPS非常高,日均訪問量非常大;

    • 數(shù)據(jù)格式固定:交易系統(tǒng)處理的數(shù)據(jù)格式非常固定;

    • 報(bào)文數(shù)據(jù)量?。好看握埱髠鬏?shù)臄?shù)據(jù)一般不超過10KB;

    • 用戶全世界分布:客戶分布在全世界的各個(gè)國家;

    • 分內(nèi)部調(diào)用和外部調(diào)用:除了API客戶直接調(diào)用的API,其他的API都是由內(nèi)部其他系統(tǒng)調(diào)用的;

    • 7×24小時(shí)不間斷服務(wù):系統(tǒng)需要提供高可用、不間斷的服務(wù)能力,以滿足不同時(shí)區(qū)客戶的交易和自動(dòng)化策略交易;

    • 外部用戶有一定技術(shù)能力:外部API客戶,一般是集成我們的API,實(shí)現(xiàn)自己的交易系統(tǒng)。

    5. 交易系統(tǒng)API網(wǎng)關(guān)面臨的問題

    問題1:流量不斷增加。

    如何合理控制流量,如何應(yīng)對突發(fā)流量,如何大限度地保障系統(tǒng)穩(wěn)定,都是重要的問題。特別是網(wǎng)關(guān)作為一個(gè)直接面對客戶的系統(tǒng),出現(xiàn)的任何問題都會(huì)放大百倍。很多千奇百怪的從來沒人遇到的問題隨時(shí)都可能出現(xiàn)。

    問題2:網(wǎng)關(guān)系統(tǒng)越來越復(fù)雜。

    現(xiàn)有的業(yè)務(wù)網(wǎng)關(guān)經(jīng)過多年發(fā)展,里面有大量的業(yè)務(wù)嵌入,并且存在多個(gè)不同的業(yè)務(wù)網(wǎng)關(guān),相互之間沒有任何關(guān)系,也沒有沉淀出基礎(chǔ)設(shè)施。

    同時(shí)技術(shù)債務(wù)太多,系統(tǒng)里硬編碼實(shí)現(xiàn)了全局性網(wǎng)關(guān)策略及很多業(yè)務(wù)規(guī)則,導(dǎo)致維護(hù)成本較大。

    問題3:API網(wǎng)關(guān)管理比較困難。

    海量并發(fā)下API的監(jiān)控指標(biāo)設(shè)計(jì)和數(shù)據(jù)的收集也是一個(gè)不小的問題。7×24小時(shí)運(yùn)行的技術(shù)支持也導(dǎo)致維護(hù)成本較高。

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

    使用短連接還是長連接,REST API還是WebSocket?業(yè)務(wù)渠道較多(多個(gè)不同產(chǎn)品線的Web、App、API等形成十幾個(gè)不同的渠道),導(dǎo)致用戶的使用行為難以控制。

    業(yè)務(wù)網(wǎng)關(guān)的設(shè)計(jì)與最佳實(shí)踐

    1. API網(wǎng)關(guān)1.0

    我們的API網(wǎng)關(guān)1.0版本是多年前開發(fā)的,是直接使用OpenResty定制的,全局的安全測試、流量的路由轉(zhuǎn)發(fā)策略、針對不同級別的限流等都是直接用Lua腳本實(shí)現(xiàn)。

    這樣就導(dǎo)致在經(jīng)歷了業(yè)務(wù)飛速發(fā)展以后,系統(tǒng)里存在非常多的相同功能或不同功能的Lua腳本,每次上線或維護(hù)都需要找到受影響的其中幾個(gè)或幾十個(gè)Lua腳本,進(jìn)行策略調(diào)整,非常不方便,策略控制的粒度也不夠細(xì)。

    2. API網(wǎng)關(guān)2.0

    在區(qū)分了流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān)以后,2017年開始實(shí)現(xiàn)了流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān)的分離,流量網(wǎng)關(guān)繼續(xù)使用OpenResty定制,只保留少量全局性、不經(jīng)常改動(dòng)的配置功能和對應(yīng)的Lua腳本。

    業(yè)務(wù)網(wǎng)關(guān)使用Vert.x實(shí)現(xiàn)的Java系統(tǒng),部署在流量網(wǎng)關(guān)和后端業(yè)務(wù)服務(wù)系統(tǒng)之間,利用Vert.x的響應(yīng)式編程能力和異步非阻塞I/O能力、分布式部署的擴(kuò)展能力,初步解決了問題1和問題2,如圖7-13所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-13

    Vert.x是一個(gè)基于事件驅(qū)動(dòng)和異步非阻塞I/O、運(yùn)行于JVM上的框架,如圖7-14所示。在Vert.x里,Verticle是最基礎(chǔ)的開發(fā)和部署單元,不同的Vert.x可以通過Event Bus傳遞數(shù)據(jù),進(jìn)而方便地實(shí)現(xiàn)高并發(fā)性能的網(wǎng)絡(luò)程序。關(guān)于Vert.x原理的分析可以參考阿里架構(gòu)師宿何的blog:

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

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-14

    Vert.x同時(shí)很好地支持了WebSocket協(xié)議,所以可以方便地實(shí)現(xiàn)支持REST API和WebSocket、完全異步的網(wǎng)關(guān)系統(tǒng),如圖7-15所示。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-15

    一個(gè)高性能的API網(wǎng)關(guān)系統(tǒng),緩存是必不可少的部分。無論分發(fā)冷熱數(shù)據(jù),降低對業(yè)務(wù)系統(tǒng)的壓力,還是作為中間數(shù)據(jù)源,為服務(wù)聚合提供高效可復(fù)用的業(yè)務(wù)數(shù)據(jù),緩存都發(fā)揮了巨大作用。

    3. API網(wǎng)關(guān)的日常監(jiān)控

    我們使用多種工具對API進(jìn)行監(jiān)控和管理,包括全鏈路訪問跟蹤、連接數(shù)統(tǒng)計(jì)分析、全世界重要國家和城市的波測訪問統(tǒng)計(jì)。網(wǎng)關(guān)技術(shù)團(tuán)隊(duì)每時(shí)每刻都關(guān)注著數(shù)據(jù)的變化趨勢。各個(gè)業(yè)務(wù)系統(tǒng)研發(fā)團(tuán)隊(duì)每天安排專人關(guān)注自己系統(tǒng)的API性能(吞吐量和延遲),推進(jìn)性能問題解決和持續(xù)優(yōu)化。這就初步解決了問題3。

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

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

    5. API網(wǎng)關(guān)的性能優(yōu)化

    API網(wǎng)關(guān)系統(tǒng)作為API服務(wù)的統(tǒng)一接入點(diǎn),為了給用戶提供最優(yōu)質(zhì)的用戶體驗(yàn),必須長期做性能優(yōu)化工作。不僅API網(wǎng)關(guān)自己做優(yōu)化,同時(shí)可以根據(jù)監(jiān)控情況,時(shí)刻發(fā)現(xiàn)各業(yè)務(wù)系統(tǒng)的API服務(wù)能力,以此為出發(fā)點(diǎn),推動(dòng)各個(gè)業(yè)務(wù)系統(tǒng)不斷優(yōu)化API性能。

    舉一個(gè)具體的例子,某個(gè)網(wǎng)關(guān)系統(tǒng)連接經(jīng)常強(qiáng)烈抖動(dòng)(如圖7-16所示),嚴(yán)重影響系統(tǒng)的穩(wěn)定性、浪費(fèi)系統(tǒng)資源,經(jīng)過排除發(fā)現(xiàn):

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

    (2)有部分API客戶的程序存在bug,而且處理速度有限,不斷地重復(fù)“斷開并重新連接”,再嘗試重新對API數(shù)據(jù)進(jìn)行處理,嚴(yán)重影響了客戶的用戶體驗(yàn)。

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

    (1)對于每天認(rèn)定的爬蟲IP,加入黑名單,直接在流量網(wǎng)關(guān)限制其訪問我們的API網(wǎng)關(guān)。

    (2)對于存在bug的API客戶,協(xié)助對方進(jìn)行問題定位和bug修復(fù),增強(qiáng)客戶使用信心。

    (3)對于處理速度和技術(shù)能力有限的客戶,基于定制的WebSocket服務(wù),使用滑動(dòng)時(shí)間窗口算法,在業(yè)務(wù)數(shù)據(jù)變化非常大時(shí),對分發(fā)的消息進(jìn)行批量優(yōu)化。

    百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)

    圖7-16

    (4)對于未登錄和識別身份的API調(diào)用,流量網(wǎng)關(guān)實(shí)現(xiàn)全局的流控策略,增加緩存時(shí)間和限制調(diào)用次數(shù),保障系統(tǒng)穩(wěn)定。

    (5)業(yè)務(wù)網(wǎng)關(guān)根據(jù)API服務(wù)的重要等級和客戶的分類,進(jìn)一步細(xì)化和實(shí)時(shí)控制網(wǎng)關(guān)策略,大限度地保障核心業(yè)務(wù)和客戶的使用。

    從監(jiān)控圖表可以看到,優(yōu)化之后的效果非常明顯,系統(tǒng)穩(wěn)定,連接數(shù)平穩(wěn)。

    本文節(jié)選自《高可用可伸縮微服務(wù)架構(gòu):基于Dubbo、Spring Cloud和Service Mesh》一書,程超,梁桂釗,秦金衛(wèi),方志斌,張逸等著。

    分享標(biāo)題:百億流量微服務(wù)網(wǎng)關(guān)的設(shè)計(jì)與實(shí)現(xiàn)-創(chuàng)新互聯(lián)
    轉(zhuǎn)載注明:http://www.muchs.cn/article40/dgiiho.html

    成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、服務(wù)器托管、營銷型網(wǎng)站建設(shè)外貿(mào)網(wǎng)站建設(shè)、外貿(mào)建站、品牌網(wǎng)站制作

    廣告

    聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

    成都seo排名網(wǎng)站優(yōu)化