馮騏 沈富可
摘? ?要:能力開(kāi)放已經(jīng)成為高校信息化建設(shè)的重點(diǎn),API體系的構(gòu)建是能力開(kāi)放的前提。傳統(tǒng)的API構(gòu)建模式依賴(lài)數(shù)據(jù)倉(cāng)庫(kù),難以支持實(shí)時(shí)性、數(shù)據(jù)寫(xiě)入等需求,基于API網(wǎng)關(guān)的模型能夠更好地解決這些問(wèn)題。文章提供了API網(wǎng)關(guān)的設(shè)計(jì)方案,給出了具體的網(wǎng)關(guān)架構(gòu)并解釋了在API網(wǎng)關(guān)的架構(gòu)下如何解決傳統(tǒng)API構(gòu)建模式面臨的困難;明確了API網(wǎng)關(guān)需要支持的授權(quán)模型;列舉了API網(wǎng)關(guān)在安全上需要實(shí)現(xiàn)的關(guān)鍵點(diǎn)。文章還通過(guò)開(kāi)源和自研兩個(gè)角度提供了API網(wǎng)關(guān)的實(shí)現(xiàn)方案,對(duì)主流的開(kāi)源API網(wǎng)關(guān)進(jìn)行了比較和討論并在自研方案中對(duì)API網(wǎng)關(guān)關(guān)鍵技術(shù)的實(shí)現(xiàn)進(jìn)行了描述,通過(guò)測(cè)試驗(yàn)證了實(shí)現(xiàn)方案的可行性。
關(guān)鍵詞:API網(wǎng)關(guān);能力開(kāi)放;認(rèn)證;授權(quán);限流;熔斷
中圖分類(lèi)號(hào):TP311.5 文獻(xiàn)標(biāo)志碼:A 文章編號(hào):1673-8454(2021)03-0061-06
一、能力開(kāi)放平臺(tái)概述
近年來(lái)隨著信息技術(shù)的不斷發(fā)展,尤其是互聯(lián)網(wǎng)服務(wù)在生活中的普遍應(yīng)用,用戶(hù)的信息素養(yǎng)也隨之提高并養(yǎng)成了“互聯(lián)網(wǎng)”式的使用習(xí)慣,因而對(duì)高校的信息化建設(shè)提出了更高的要求。傳統(tǒng)信息系統(tǒng)的用戶(hù)體驗(yàn)如何滿足互聯(lián)網(wǎng)時(shí)代用戶(hù)的要求,成為當(dāng)下高校信息化建設(shè)的痛點(diǎn)之一。而能力開(kāi)放、引入競(jìng)爭(zhēng)、共同開(kāi)發(fā)是解決該痛點(diǎn)的有效手段。[1]能力開(kāi)放是指通過(guò)數(shù)據(jù)的治理和業(yè)務(wù)的梳理,將核心數(shù)據(jù)與核心服務(wù)通過(guò)API[2]的形式開(kāi)放,降低應(yīng)用提供方參與信息化建設(shè)的門(mén)檻,引入更多的競(jìng)爭(zhēng),吸引各方面的開(kāi)發(fā)者共同參與信息化建設(shè),形成良性的信息化建設(shè)生態(tài),提升信息化水平。
能力開(kāi)放平臺(tái)在互聯(lián)網(wǎng)領(lǐng)域已經(jīng)比較成熟,阿里、百度、騰訊等知名互聯(lián)網(wǎng)企業(yè)都建設(shè)有自己的能力開(kāi)放平臺(tái),并且建立了良好的開(kāi)發(fā)者生態(tài)體系。例如阿里旗下有阿里云開(kāi)發(fā)者平臺(tái)、螞蟻金服開(kāi)放平臺(tái)等;百度旗下有百度地圖開(kāi)放平臺(tái)、百度AI開(kāi)放平臺(tái)等;騰訊旗下有微信開(kāi)放平臺(tái)和QQ開(kāi)放平臺(tái)等。以微信開(kāi)放平臺(tái)為例,根據(jù)2018年的《微信就業(yè)影響力報(bào)告》[3],2018年基于微信的小程序數(shù)量超過(guò)100萬(wàn)個(gè),第三方服務(wù)商超過(guò)3萬(wàn)家,覆蓋細(xì)分行業(yè)200余個(gè)。由于開(kāi)放平臺(tái)大幅降低了應(yīng)用開(kāi)發(fā)的門(mén)檻,大部分第三方服務(wù)商的規(guī)模不超過(guò)50人,近50%的小程序都能夠在2周以?xún)?nèi)完成開(kāi)發(fā)??梢?jiàn)能力開(kāi)放能夠顯著地幫助開(kāi)發(fā)者更簡(jiǎn)單更高效地參與應(yīng)用建設(shè)。
實(shí)現(xiàn)能力開(kāi)放平臺(tái)的基礎(chǔ)是各項(xiàng)數(shù)據(jù)和服務(wù)的API構(gòu)建。傳統(tǒng)的API構(gòu)建模式大多基于全域的數(shù)據(jù)整合,核心是抓取各條線的業(yè)務(wù)系統(tǒng)數(shù)據(jù),統(tǒng)一整合。本質(zhì)上是先構(gòu)建數(shù)據(jù)倉(cāng)庫(kù),[4]再基于數(shù)據(jù)倉(cāng)庫(kù)構(gòu)建API,其結(jié)構(gòu)如圖1所示。
這種模式的優(yōu)點(diǎn)在于數(shù)據(jù)集,因此很容易實(shí)現(xiàn)跨業(yè)務(wù)的聚合API,API開(kāi)發(fā)速度比較快,API風(fēng)格也會(huì)比較統(tǒng)一。然而這種模式存在幾個(gè)問(wèn)題:①由于存在同步周期,API無(wú)法實(shí)時(shí)反饋數(shù)據(jù),通常存在1天左右的延遲。②只支持?jǐn)?shù)據(jù)查詢(xún)API,不支持寫(xiě)入,因此多業(yè)務(wù)聯(lián)動(dòng)式(比如一站式平臺(tái))的API需求無(wú)法得到支持。③業(yè)務(wù)系統(tǒng)無(wú)法感知API調(diào)用過(guò)程,調(diào)用日志僅API模塊可查。④當(dāng)下高校信息化環(huán)境中,由于業(yè)務(wù)系統(tǒng)大多由業(yè)務(wù)部門(mén)主導(dǎo)建設(shè),結(jié)合第三條,在業(yè)務(wù)系統(tǒng)升級(jí)變更時(shí),容易導(dǎo)致數(shù)據(jù)同步失效,從而導(dǎo)致API失效。
本文觀點(diǎn)是將API建設(shè)聚焦在認(rèn)證、授權(quán)、限流、熔斷等核心功能上,即構(gòu)建API網(wǎng)關(guān)。具體的業(yè)務(wù)API交由業(yè)務(wù)系統(tǒng)本身實(shí)現(xiàn),由API網(wǎng)關(guān)提供安全可控的轉(zhuǎn)發(fā)。因此能夠解決傳統(tǒng)方案存在的問(wèn)題。文章詳述了API網(wǎng)關(guān)的架構(gòu)設(shè)計(jì)并給出了具體的實(shí)現(xiàn)方案。
二、設(shè)計(jì)
本章將詳述API網(wǎng)關(guān)的架構(gòu)設(shè)計(jì)、授權(quán)模型和安全問(wèn)題,給出了API網(wǎng)關(guān)的關(guān)鍵要素和參考模型。
1.API網(wǎng)關(guān)架構(gòu)
每一個(gè)提供數(shù)據(jù)的業(yè)務(wù)系統(tǒng)都可以視為數(shù)據(jù)的“生產(chǎn)者”,每一個(gè)需求數(shù)據(jù)的業(yè)務(wù)系統(tǒng)也可以視為數(shù)據(jù)的“消費(fèi)者”。連接“消費(fèi)者”與“生產(chǎn)者”之間的是API網(wǎng)關(guān)。這看起來(lái)有點(diǎn)像企業(yè)服務(wù)總線(ESB),然而ESB更側(cè)重企業(yè)內(nèi)部的數(shù)據(jù)通訊,更注重協(xié)議轉(zhuǎn)換、數(shù)據(jù)轉(zhuǎn)換、服務(wù)編排、消息機(jī)制等,對(duì)應(yīng)用的侵入性更強(qiáng)。而API網(wǎng)關(guān)更側(cè)重接口的外部開(kāi)放,更注重認(rèn)證、授權(quán)、限流、熔斷等,接口遵循REST API轉(zhuǎn)發(fā),對(duì)應(yīng)用沒(méi)有侵入性。典型的API 網(wǎng)關(guān)架構(gòu)如圖2所示。
對(duì)于接入API網(wǎng)關(guān)的業(yè)務(wù)系統(tǒng),都必須提供REST API接口,但不必考慮認(rèn)證、授權(quán)、限流等安全控制問(wèn)題,這部分工作交由API網(wǎng)關(guān)來(lái)完成。無(wú)論外部應(yīng)用請(qǐng)求還是內(nèi)部應(yīng)用請(qǐng)求,均通過(guò)API網(wǎng)關(guān)來(lái)統(tǒng)一授權(quán)?;仡檪鹘y(tǒng)模式下我們面臨的4個(gè)問(wèn)題,API網(wǎng)關(guān)模型的方案都能夠很好地解決。①由于業(yè)務(wù)系統(tǒng)直接提供API,因此數(shù)據(jù)必然是真實(shí)的。②由于業(yè)務(wù)系統(tǒng)直接提供API,因此可以支持寫(xiě)入類(lèi)的API服務(wù)。③所有通過(guò)授權(quán)的API請(qǐng)求都會(huì)轉(zhuǎn)發(fā)到業(yè)務(wù)系統(tǒng)的API上,因此業(yè)務(wù)系統(tǒng)能夠拿到全部合法的API調(diào)用日志。而不合法的請(qǐng)求部分已經(jīng)被API網(wǎng)關(guān)攔截,事實(shí)上也降低了后端API的負(fù)擔(dān)。④由于API由業(yè)務(wù)系統(tǒng)直接提供,因此在業(yè)務(wù)系統(tǒng)升級(jí)時(shí),如果API發(fā)生變更,只需要重新發(fā)布API網(wǎng)關(guān)的路由即可,無(wú)需重新對(duì)接數(shù)據(jù)。事實(shí)上業(yè)務(wù)系統(tǒng)升級(jí)通常會(huì)考慮API向前兼容性(例如老版本API以/api/v1發(fā)布,新版本以/api/v2發(fā)布),因此這一切過(guò)程通常不會(huì)影響API服務(wù)的可用性。
2.授權(quán)模型
API網(wǎng)關(guān)的重要意義之一在于提供統(tǒng)一的授權(quán)模型,使不同后端API調(diào)用的開(kāi)放模式保持一致,從而降低應(yīng)用開(kāi)發(fā)者的接入負(fù)擔(dān),也簡(jiǎn)化了權(quán)限管理的運(yùn)維。從授權(quán)模式上來(lái)講,應(yīng)當(dāng)盡可能選用互聯(lián)網(wǎng)中公認(rèn)的事實(shí)標(biāo)準(zhǔn),簡(jiǎn)化應(yīng)用的開(kāi)發(fā)。根據(jù)OpenAPI[5]規(guī)范,授權(quán)方式大致可以分為4類(lèi):①HTTP authentication schemes,即HTTP header中含有Authorization字段。②API keys。③oAuth2 。④OpenID Connect Discovery。這其中前兩種主要面向應(yīng)用直接授權(quán),即應(yīng)用方作為客戶(hù)端(后簡(jiǎn)稱(chēng)客戶(hù)端)調(diào)用API時(shí)只需要攜帶約定的Authorization字段或者Key,后兩種則需要用戶(hù)進(jìn)行授權(quán)允許之后,才能夠獲取token,并且該token只能查詢(xún)授權(quán)用戶(hù)相關(guān)的內(nèi)容。API網(wǎng)關(guān)應(yīng)該至少實(shí)現(xiàn)APIkeys和oAuth2這兩種授權(quán)模式。
(1)APIKeys授權(quán)
APIkeys授權(quán)通常用于內(nèi)部的數(shù)據(jù)交互,API網(wǎng)關(guān)通過(guò)實(shí)現(xiàn)約定的密鑰直接授權(quán)給客戶(hù)端,客戶(hù)端在請(qǐng)求中攜帶事先約定的授權(quán)密鑰即可以調(diào)用允許的API??梢苑旁诓樵?xún)參數(shù)或者Header中。圖3展示了請(qǐng)求的示例。
每個(gè)接入API網(wǎng)關(guān)的客戶(hù)端必須分配獨(dú)立的密鑰,由于密鑰通常不設(shè)有效期,相當(dāng)于一個(gè)永久性授權(quán),因此從安全上考慮,通常對(duì)客戶(hù)端再增加IP地址限制。即獨(dú)立唯一的“密鑰+合法的IP地址”才能合法地得到授權(quán)。
(2)OAuth2授權(quán)
OAuth2[6]是在互聯(lián)網(wǎng)應(yīng)用中廣泛使用的授權(quán)模式。其特點(diǎn)是客戶(hù)端必須得到用戶(hù)的授權(quán)(authorization grant),才能獲得令牌(access token)。OAuth 2.0定義了4種授權(quán)方式:①授權(quán)碼模式;②簡(jiǎn)化模式;③密碼模式;④客戶(hù)端模式。
授權(quán)碼模式是標(biāo)準(zhǔn)的用戶(hù)授權(quán)結(jié)構(gòu),客戶(hù)端必須經(jīng)過(guò)用戶(hù)授權(quán)才能獲取token;簡(jiǎn)化模式直接通過(guò)瀏覽器請(qǐng)求token,因此token對(duì)用戶(hù)是可見(jiàn)的,存在一定的token泄露風(fēng)險(xiǎn);密碼模式中用戶(hù)需要直接向客戶(hù)端輸入密碼,而客戶(hù)端必須承諾不會(huì)儲(chǔ)存用戶(hù)密碼,通常不會(huì)采取這種模式;客戶(hù)端模式無(wú)需用戶(hù)授權(quán)就可以直接獲取token,與APIkeys場(chǎng)景相類(lèi)似,但是token存在有效期。API網(wǎng)關(guān)應(yīng)該至少要實(shí)現(xiàn)授權(quán)碼模式和客戶(hù)端模式的oAuth2支持。
授權(quán)碼模式(authorization code)的流程示意如圖4所示。
其步驟如下:
(A)用戶(hù)訪問(wèn)客戶(hù)端,后者將前者導(dǎo)向認(rèn)證服務(wù)器。
(B)用戶(hù)選擇是否給予客戶(hù)端授權(quán)。
(C)假設(shè)用戶(hù)給予授權(quán),認(rèn)證服務(wù)器將用戶(hù)導(dǎo)向客戶(hù)端事先指定的“重定向URI”(redirection URI),同時(shí)附上一個(gè)授權(quán)碼。
(D)客戶(hù)端收到授權(quán)碼,附上早先的“重定向URI”,向認(rèn)證服務(wù)器申請(qǐng)令牌。這一步是在客戶(hù)端后臺(tái)的服務(wù)器上完成的,對(duì)用戶(hù)不可見(jiàn)。
(E)認(rèn)證服務(wù)器核對(duì)了授權(quán)碼和重定向URI,確認(rèn)無(wú)誤后,向客戶(hù)端發(fā)送訪問(wèn)令牌(access token)和更新令牌(refresh token)。
客戶(hù)端模式(Client Credentials Grant)的流程如圖5所示。
其步驟如下:
(A)客戶(hù)端向認(rèn)證服務(wù)器進(jìn)行身份認(rèn)證,并要求一個(gè)訪問(wèn)令牌。
(B)認(rèn)證服務(wù)器確認(rèn)無(wú)誤后,向客戶(hù)端提供訪問(wèn)令牌。
3.安全問(wèn)題
API網(wǎng)關(guān)與一般的反向代理的重大差別就在于他集成了授權(quán)和安全的功能,從而簡(jiǎn)化了后端API開(kāi)發(fā)工作,可以更專(zhuān)注于業(yè)務(wù)本身。安全方面,API網(wǎng)關(guān)需要支持以下三個(gè)部分:①WAF防護(hù);②請(qǐng)求限流;③超時(shí)熔斷。
(1)WAF防護(hù)
REST API基于Web服務(wù),因此也容易遭受各種Web上的攻擊。尤其是注入類(lèi)的攻擊對(duì)后端API的危害較大,API網(wǎng)關(guān)層面的保護(hù)對(duì)提高整個(gè)API體系的安全性至關(guān)重要。我們可以在API網(wǎng)關(guān)內(nèi)嵌入WAF模塊來(lái)對(duì)請(qǐng)求的流量進(jìn)行清洗。例如在一些基于lua和nginx的API網(wǎng)關(guān)結(jié)構(gòu)中,可以直接為nginx增加一些第三方WAF模塊來(lái)實(shí)現(xiàn)WAF防護(hù)支持。
另一種方案則是在API網(wǎng)關(guān)之前再疊加一層反向代理模式的WAF節(jié)點(diǎn)。這種模式會(huì)存在一個(gè)額外的節(jié)點(diǎn),但是WAF本身能夠與API網(wǎng)關(guān)松耦合,因此可以任意選擇或者更換WAF,比如選擇一些經(jīng)過(guò)市場(chǎng)驗(yàn)證的商用化WAF產(chǎn)品。
(2)請(qǐng)求限流
API網(wǎng)關(guān)容易遭受的另一類(lèi)攻擊是各種拒絕服務(wù)(DoS)攻擊,因此請(qǐng)求限流必不可少。同時(shí)請(qǐng)求量過(guò)高超過(guò)了后端服務(wù)能夠承載的上限,也可能導(dǎo)致服務(wù)不可用,需要對(duì)服務(wù)進(jìn)行降級(jí)限流。另一方面,由于應(yīng)用的開(kāi)發(fā)用途不同,限流的控制力度也有差異,因此需要對(duì)不同的應(yīng)用提供區(qū)別的限流控制。
常見(jiàn)的限流算法有計(jì)數(shù)器、漏桶、令牌桶等,計(jì)數(shù)器算法限定一段時(shí)間內(nèi)的請(qǐng)求總數(shù),但是如果請(qǐng)求總數(shù)被提前耗盡,則剩余時(shí)間內(nèi)無(wú)法完成任何請(qǐng)求,即“突刺現(xiàn)象”。漏桶算法[7]將所有請(qǐng)求先臨時(shí)放在“桶”里,然后以恒定的速度處理請(qǐng)求,但是無(wú)法應(yīng)對(duì)短時(shí)間的突發(fā)流量。令牌桶算法[8]以恒定的速率生產(chǎn)令牌放到“桶”中,處理請(qǐng)求時(shí)先獲取令牌,再完成請(qǐng)求處理。因此如果“桶”本身是滿的,那么就可以快速消耗掉所有令牌,從而支持突發(fā)流量請(qǐng)求。在令牌消耗完以后,由于令牌依然保持恒定速率生產(chǎn),因此還可以繼續(xù)保持一定的速率處理請(qǐng)求。
因此,API網(wǎng)關(guān)的請(qǐng)求限流必須要實(shí)現(xiàn)以下3點(diǎn):①限流可以基于應(yīng)用(即開(kāi)發(fā)者賬號(hào))做區(qū)分限制。②支持令牌桶等限流算法以提供更好的響應(yīng)服務(wù)。③限流算法中的數(shù)據(jù)存儲(chǔ)基于外部服務(wù)(比如redis),API網(wǎng)關(guān)只做調(diào)用檢查,保持網(wǎng)關(guān)本身無(wú)狀態(tài)。④支持服務(wù)降級(jí),在服務(wù)能力不足時(shí)降低服務(wù)等級(jí)以避免異常擴(kuò)大化。
(3)超時(shí)熔斷
熔斷一詞源于電子工程中的熔斷器,即保險(xiǎn)絲。當(dāng)負(fù)載過(guò)大時(shí)保險(xiǎn)絲燒毀斷開(kāi)電路以避免電路電器受損壞。由于API網(wǎng)關(guān)承載了整個(gè)能力開(kāi)放平臺(tái)的所有API服務(wù),某一個(gè)后端API服務(wù)異常超時(shí)的時(shí)候必須不影響到其他的API服務(wù)。因此API網(wǎng)關(guān)也需要熔斷的支持,在檢測(cè)到某個(gè)后端API服務(wù)異常超時(shí)后,停止繼續(xù)轉(zhuǎn)發(fā)數(shù)據(jù),避免因大量的超時(shí)堆積線程而導(dǎo)致網(wǎng)關(guān)服務(wù)不可用。這樣也能夠降低故障后端的負(fù)載,從而幫助其更快地恢復(fù)服務(wù)。熔斷的算法模型如圖6所示。
當(dāng)后端API的超時(shí)越過(guò)一定閾值之后,進(jìn)入熔斷打開(kāi)模式,在熔斷時(shí)間內(nèi)所有轉(zhuǎn)發(fā)給該服務(wù)的請(qǐng)求都直接返回500錯(cuò)誤。當(dāng)熔斷時(shí)間結(jié)束后,進(jìn)入熔斷半打開(kāi)模式,隨機(jī)的挑選部分請(qǐng)求進(jìn)入后端,如果請(qǐng)求返回成功,則進(jìn)入熔斷關(guān)閉模式,完全恢復(fù)服務(wù)。如果請(qǐng)求依然超時(shí)失敗,則回到熔斷打開(kāi)模式繼續(xù)阻斷請(qǐng)求。
三、實(shí)現(xiàn)
API網(wǎng)關(guān)作為微服務(wù)整合的重要組件,在互聯(lián)網(wǎng)領(lǐng)域已經(jīng)有許多實(shí)現(xiàn)方案,其中部分已經(jīng)開(kāi)源。本文從功能、性能等方面對(duì)比了一些主流的開(kāi)源API網(wǎng)關(guān),討論了在高校應(yīng)用開(kāi)源方案的可行性;也給出了自研API網(wǎng)關(guān)中的關(guān)鍵技術(shù)實(shí)現(xiàn)方案,并提供了測(cè)試數(shù)據(jù)驗(yàn)證了可行性。
1.開(kāi)源實(shí)現(xiàn)方案
由于API網(wǎng)關(guān)在互聯(lián)網(wǎng)服務(wù)中的普遍應(yīng)用,業(yè)內(nèi)已經(jīng)存在一些開(kāi)源方案,這里選取了比較典型且風(fēng)格差異較大的三種討論:①基于OpenResty的Kong。②基于Go語(yǔ)言的Tyk。③基于JVM的Zuul。
Kong是一個(gè)基于OpenResty[9]的開(kāi)源API網(wǎng)關(guān)。OpenResty是一個(gè)基于Nginx和Lua的高性能Web平臺(tái)。其內(nèi)部集成了大量精良的 Lua 庫(kù)、第三方模塊以及大多數(shù)的依賴(lài)項(xiàng)。它能夠讓業(yè)務(wù)邏輯通過(guò)Lua動(dòng)態(tài)腳本的方式直接運(yùn)行在Nginx內(nèi)部,利用Nginx的非阻塞I/O模型和各種現(xiàn)有模塊,實(shí)現(xiàn)高性能且靈活的Web開(kāi)發(fā)。Kong就是在OpenResty基礎(chǔ)上通過(guò)lua腳本實(shí)現(xiàn)網(wǎng)關(guān)功能,并且通過(guò)插件機(jī)制能夠?qū)崿F(xiàn)很好的擴(kuò)展支持。其中API反向代理轉(zhuǎn)發(fā)部分通過(guò)Nginx實(shí)現(xiàn),認(rèn)證授權(quán)、限流、熔斷、WAF等均通過(guò)對(duì)應(yīng)的插件實(shí)現(xiàn)。但插件通常并不能100%符合實(shí)際需求,比較好的應(yīng)用還是需要能夠?qū)ua腳本進(jìn)行一些二次開(kāi)發(fā)。例如oAuth插件只負(fù)責(zé)了授權(quán)部分,當(dāng)出于客戶(hù)端授權(quán)碼模式,用戶(hù)認(rèn)證的部分還是需要自己實(shí)現(xiàn)一個(gè)認(rèn)證接口。Kong的商業(yè)版本提供了一個(gè)Dashboard的UI,開(kāi)源版本則必須通過(guò)API進(jìn)行配置。
Tyk是一個(gè)基于Go[10]語(yǔ)言開(kāi)發(fā)的API網(wǎng)關(guān),也有相當(dāng)好的性能。Tyk也支持插件模式,插件可以用Lua、Python或者JavaScript等解釋性語(yǔ)言來(lái)寫(xiě),通過(guò)插件可以擴(kuò)展后端服務(wù)支持gRPC。Tyk的主要功能都通過(guò)主程序直接支持,插件主要用于額外的功能,比如為oAuth授權(quán)中的認(rèn)證添加認(rèn)證接口。Tyk也有商業(yè)版本,其免費(fèi)版本限制只能部署一個(gè)單機(jī)節(jié)點(diǎn),不支持多機(jī)部署。但是Tyk的免費(fèi)版本也提供Dashboard UI。
Zuul是由Netflix公司開(kāi)源的API網(wǎng)關(guān),是Netflix開(kāi)源的SpringCloud微服務(wù)框架中的一個(gè)組件。它實(shí)際上不是一個(gè)完整的產(chǎn)品,需要結(jié)合SpringCloud中的其他組件共同開(kāi)發(fā)完成。如果項(xiàng)目本身采用SpringCloud,那么結(jié)合Zuul會(huì)非常簡(jiǎn)單和快捷。
表1對(duì)比了三種API網(wǎng)關(guān)的主要差異。
2.自研實(shí)現(xiàn)方案
開(kāi)源的API網(wǎng)關(guān)方案雖然基本都能夠滿足需求,然而由于開(kāi)源軟件需要綜合考慮絕大部分用戶(hù)的需求,因此設(shè)計(jì)會(huì)比較復(fù)雜,配置比較繁重,導(dǎo)致學(xué)習(xí)曲線比較陡峭。同時(shí)有些偏個(gè)性化內(nèi)容,開(kāi)源軟件通常也無(wú)法直接支持,需要編寫(xiě)插件或自己二次開(kāi)發(fā)實(shí)現(xiàn),因此即便選用開(kāi)源方案,也還是需要有一定的軟件開(kāi)發(fā)基礎(chǔ),否則很難發(fā)揮出軟件的優(yōu)勢(shì)。
另一方面,如果我們只需要簡(jiǎn)單實(shí)現(xiàn)一個(gè)API網(wǎng)關(guān),不需要考慮過(guò)多的全面性,自研開(kāi)發(fā)也是一種選擇。實(shí)際上基于Zuul的API網(wǎng)關(guān)方案已經(jīng)非常接近基于SpringCloud進(jìn)行開(kāi)發(fā)了,由于技術(shù)棧偏好的差異,本文討論通過(guò)Go語(yǔ)言自研開(kāi)發(fā)API網(wǎng)關(guān)的一些關(guān)鍵技術(shù)。
我們使用Go語(yǔ)言中的Gin框架開(kāi)發(fā)API網(wǎng)關(guān)的Web服務(wù),使用MySQL儲(chǔ)存配置信息,使用redis作為外部組件提供緩存,并配合限流算法進(jìn)行限流。
API網(wǎng)關(guān)首先是一個(gè)HTTP服務(wù)的反向代理服務(wù)器。因此我們需要先實(shí)現(xiàn)API請(qǐng)求的反向代理。Go語(yǔ)言的HTTP標(biāo)準(zhǔn)庫(kù)對(duì)http服務(wù)有非常完整的支持,其中就自帶了反向代理的功能。而Gin框架是net/http包的一個(gè)封裝,兼容Go的HTTP標(biāo)準(zhǔn)庫(kù),因此只需要調(diào)用httputil.ReverseProxy就能夠完成反向代理API請(qǐng)求的功能。
Gin可以通過(guò)中間件(middware)的方式對(duì)HTTP路由增加授權(quán)支持。我們只需要將授權(quán)的代碼通過(guò)中間件的形式加載到每一個(gè)需要授權(quán)的路由上即可。其中APIKeys用于授權(quán)的Key、oAuth2分配的client_id和client_secret存在MySQL中,生成的token則放在redis內(nèi),通過(guò)redis的key有效期自動(dòng)實(shí)現(xiàn)token的過(guò)期。在oAuth2的授權(quán)碼模式中,認(rèn)證部分與學(xué)校的統(tǒng)一身份認(rèn)證進(jìn)行集成。
限流算法采用令牌桶算法,令牌計(jì)數(shù)器和時(shí)間計(jì)數(shù)器均儲(chǔ)存在redis中。由于redis是單線程的,天然擁有并發(fā)下的原子性,可以確保多臺(tái)水平擴(kuò)展的API網(wǎng)關(guān)的限流策略一致。
熔斷在SpringCloud中有一個(gè)知名的開(kāi)源組件hystrix,現(xiàn)在它也有Go語(yǔ)言的版本hystrix-go,所以只需要用hystrix-go嵌入代碼就能很快實(shí)現(xiàn)熔斷功能。
由于目前Golang生態(tài)中尚缺乏優(yōu)秀的WAF模塊,所以我們沒(méi)有在網(wǎng)關(guān)中嵌入WAF,而使用外置WAF反向代理API網(wǎng)關(guān)的模式發(fā)布服務(wù)。這樣實(shí)際上https卸載和IP黑名單也可以由WAF來(lái)完成,API網(wǎng)關(guān)本身可以簡(jiǎn)化。在我們的生成環(huán)境中,我們采用了一款商用WAF產(chǎn)品作為API網(wǎng)關(guān)的服務(wù)發(fā)布。
整個(gè)開(kāi)發(fā)架構(gòu)如圖7所示。
3.性能測(cè)試
API網(wǎng)關(guān)由于需要承載所有后端API的請(qǐng)求,因此性能不可以存在瓶頸。我們使用一臺(tái)4核心CPU、16G、50G硬盤(pán)的服務(wù)器對(duì)自研的API網(wǎng)關(guān)和開(kāi)源API網(wǎng)關(guān)進(jìn)行了性能對(duì)比。由于Zuul需要開(kāi)發(fā)集成才能使用,因此這里只對(duì)比了Kong和Tyk。所有的軟件都基于Docker部署。測(cè)試對(duì)比了無(wú)認(rèn)證授權(quán)下的性能與APIkeys下的性能對(duì)比。由于oAuth2需要另外開(kāi)發(fā)認(rèn)證接口,未測(cè)試oAuth2部分的性能,但由于換取到access_token后,oAuth2下的令牌檢查與APIkeys沒(méi)有實(shí)質(zhì)差異,因此其性能應(yīng)該與APIkeys相仿。
測(cè)試基于wrk,采用60秒100個(gè)并發(fā)請(qǐng)求。結(jié)果如圖8所示。
基于Nginx的Kong性能還是最好的,自研的性能略低一些,但比Tyk的性能好,能夠滿足生產(chǎn)環(huán)境的性能要求。當(dāng)然原因是自研方案結(jié)構(gòu)簡(jiǎn)單,功能相對(duì)Tyk比較少。后續(xù)加入更多的功能模塊,例如性能埋點(diǎn)、格式化日志等之后,性能可能會(huì)隨之有所下降。但是輕量化開(kāi)發(fā)、快速迭代本來(lái)就是自主研發(fā)的特點(diǎn)。先搭建框架,實(shí)現(xiàn)基本功能,后續(xù)根據(jù)實(shí)際需要增加功能模塊是比較務(wù)實(shí)的自研模式。
四、結(jié)語(yǔ)
API網(wǎng)關(guān)是高校構(gòu)建能力開(kāi)放平臺(tái)的核心,也是進(jìn)一步實(shí)現(xiàn)高校信息化互聯(lián)互通、一站式服務(wù)的基礎(chǔ)?;贏PI網(wǎng)關(guān)的方案可以很好地解決傳統(tǒng)模式下面臨的一些問(wèn)題:
(1)API數(shù)據(jù)的實(shí)時(shí)性問(wèn)題——由于API網(wǎng)關(guān)方案直接轉(zhuǎn)發(fā)業(yè)務(wù)方API接口,不存在數(shù)據(jù)同步。所以能夠天然支持?jǐn)?shù)據(jù)實(shí)時(shí)性。
(2)數(shù)據(jù)寫(xiě)入問(wèn)題——由于API網(wǎng)關(guān)方案直接轉(zhuǎn)發(fā)業(yè)務(wù)方API接口,因此只要業(yè)務(wù)API提供數(shù)據(jù)寫(xiě)入功能,API網(wǎng)關(guān)即可以將其發(fā)布。
(3)業(yè)務(wù)方調(diào)用日志問(wèn)題——API網(wǎng)關(guān)采取反向代理模式,業(yè)務(wù)方無(wú)需依賴(lài)網(wǎng)關(guān)也能夠獲取完整的請(qǐng)求日志。
(4)升級(jí)變更的問(wèn)題——API網(wǎng)關(guān)提供了強(qiáng)的用戶(hù)感知度。并且給予的反向代理模式能夠很快切換API路徑,因此能夠快速響應(yīng)業(yè)務(wù)接口的升級(jí)變更影響。
本文詳述了API網(wǎng)關(guān)的設(shè)計(jì)模式和關(guān)鍵要素,并給出了包含開(kāi)源和自研兩種實(shí)施方案。對(duì)高校API網(wǎng)關(guān)的構(gòu)建具有一定的參考價(jià)值,對(duì)商業(yè)API網(wǎng)關(guān)產(chǎn)品的服務(wù)定位和開(kāi)發(fā)也有一定的參考意義。
本文給出的自研實(shí)現(xiàn)方案基于Golang語(yǔ)言、redis和MySql技術(shù)棧,對(duì)其他技術(shù)棧的開(kāi)發(fā)者參考價(jià)值相對(duì)較小。但是實(shí)現(xiàn)的算法和思路沒(méi)有技術(shù)棧綁定,使用任何技術(shù)棧開(kāi)發(fā)都可以重新實(shí)現(xiàn)。
參考文獻(xiàn):
[1]馬琳,宋俊德,宋美娜.開(kāi)放平臺(tái):運(yùn)營(yíng)模式與技術(shù)架構(gòu)研究綜述[J].電信科學(xué),2012(6):125-140.
[2]馮騏,馬晨輝,沈富可.基于Metadata的監(jiān)控?cái)?shù)據(jù) API設(shè)計(jì)與實(shí)現(xiàn)[J].四川大學(xué)學(xué)報(bào)(自然科學(xué)版),2019(3):431-436.
[3]中國(guó)信息通信研究院,騰訊.微信就業(yè)影響力報(bào)告[R/OL]. http://www.caict.ac.cn/kxyj/qwfb/ztbg/201903/P020190304620742061060.pdf.
[4]張寧,賈自艷,史忠植.數(shù)據(jù)倉(cāng)庫(kù)中ETL技術(shù)的研究[J].計(jì)算機(jī)工程與應(yīng)用,2002(24):213-216.
[5]Luis López-Fernández,Boni García,Micael Gallego,et al.Designing and evaluating the usability of an API for real-time multimedia services in the Internet[J]. Multimedia Tools and Applications,2017,76(12):14247-14304l.
[6]時(shí)子慶,劉金蘭,譚曉華.基于OAuth2.0的認(rèn)證授權(quán)技術(shù)[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2012(3):260-264.
[7]蔣志剛,李樂(lè)民.ATM網(wǎng)絡(luò)中突發(fā)業(yè)務(wù)的漏桶算法分析[J].電子學(xué)報(bào),1995(1):8-14.
[8]李曉利,郭宇春.QoS技術(shù)中令牌桶算法實(shí)現(xiàn)方式比較[J].中興通訊技術(shù),2007(3):56-60.
[9]靳瑩.基于緩存技術(shù)的內(nèi)容管理系統(tǒng)研究[D].長(zhǎng)春:吉林大學(xué),2014.
[10]Peter H.Welch,Adam T.Sampson,Jan B,et al.Serving Web Content with Dynamic Process Networks in Go[J].Concurrent Systems Engineering Series,2011:68.
(編輯:王天鵬)