Chris Richardson曾經(jīng)在 他的博客 上詳細(xì)介紹過(guò)API網(wǎng)關(guān),包括API網(wǎng)關(guān)的背景、解決方案以及案例。對(duì)于大多數(shù)基于微服務(wù)的應(yīng)用程序而言,API網(wǎng)關(guān)都應(yīng)該是系統(tǒng)的入口,它會(huì)負(fù)責(zé)服務(wù)請(qǐng)求路由、組合及協(xié)議轉(zhuǎn)換。如Chris所言,在微服務(wù)的應(yīng)用程序中,客戶(hù)端和微服務(wù)之間的交互,有如下幾個(gè)挑戰(zhàn):
微服務(wù)提供的API粒度通常與客戶(hù)端的需求不同,微服務(wù)一般提供細(xì)粒度的API,也就是說(shuō)客戶(hù)端需要與多個(gè)服務(wù)進(jìn)行交互。
不同的客戶(hù)端需要不同的數(shù)據(jù),不同類(lèi)型客戶(hù)端的網(wǎng)絡(luò)性能不同。
服務(wù)的劃分可能會(huì)隨時(shí)間而變化,因此需要對(duì)客戶(hù)端隱藏細(xì)節(jié)。
那API網(wǎng)關(guān)具體是如何解決這些問(wèn)題的,在API網(wǎng)關(guān)的落地上,需要注意哪些地方,就這些問(wèn)題,InfoQ編輯采訪(fǎng)了普元主任架構(gòu)師王延炯,與他一起探討了API網(wǎng)關(guān)的來(lái)龍去脈。
InfoQ:談?wù)勀闼斫獾腁PI網(wǎng)關(guān),以及API網(wǎng)關(guān)出現(xiàn)的背景?
王延炯:API Gateway(API GW / API 網(wǎng)關(guān)),顧名思義,是出現(xiàn)在系統(tǒng)邊界上的一個(gè)面向API的、串行集中式的強(qiáng)管控服務(wù),這里的邊界是企業(yè)IT系統(tǒng)的邊界。
在微服務(wù)概念的流行之前,API GW的實(shí)體就已經(jīng)誕生了,這時(shí)的主要應(yīng)用場(chǎng)景是OpenAPI,也就是開(kāi)放平臺(tái),面向的是企業(yè)外部合作伙伴,對(duì)于這個(gè)應(yīng)用場(chǎng)景,相信接觸的人會(huì)比較多。當(dāng)在微服務(wù)概念流行起來(lái)之后,API網(wǎng)關(guān)似乎成了在上層應(yīng)用層集成的標(biāo)配組件。
其實(shí),在我所經(jīng)歷過(guò)的項(xiàng)目中,API GW的定位主要有五類(lèi):
面向Web App這類(lèi)場(chǎng)景,在物理形態(tài)上類(lèi)似前后端分離,此時(shí)的Web App已經(jīng)不是全功能的Web App,而是根據(jù)場(chǎng)景定制、場(chǎng)景化的App。
面向Mobile App這類(lèi)場(chǎng)景,移動(dòng)App是后端Service的使用者,此時(shí)的API GW還需要承擔(dān)一部分MDM(此處是指移動(dòng)設(shè)備管理,不是主數(shù)據(jù)管理)的職能。
面向Partner OpenAPI這類(lèi)場(chǎng)景,主要為了滿(mǎn)足業(yè)務(wù)形態(tài)對(duì)外開(kāi)放,與企業(yè)外部合作伙伴建立生態(tài)圈,此時(shí)的API GW需要增加配額、流控、令牌等一系列安全管控功能。
面向Partner ExternalAPI這類(lèi)場(chǎng)景,業(yè)界提的比較少,很多時(shí)候系統(tǒng)的建設(shè),都是為了滿(mǎn)足企業(yè)自身業(yè)務(wù)的需要,實(shí)現(xiàn)對(duì)企業(yè)自有業(yè)務(wù)的映射。當(dāng)互聯(lián)網(wǎng)形態(tài)逐漸影響傳統(tǒng)企業(yè)時(shí),很多系統(tǒng)都會(huì)為了導(dǎo)入流量或者內(nèi)容,依賴(lài)外部合作伙伴的能力,一些典型的例子就是使用「合作方賬號(hào)登錄」、「使用第三方支付平臺(tái)支付」等等,這些對(duì)于企業(yè)內(nèi)部來(lái)說(shuō),都是一些外部能力。此時(shí)的API GW就需要在邊界上,為企業(yè)內(nèi)部Service 統(tǒng)一調(diào)用外部的API做統(tǒng)一的認(rèn)證、(多租戶(hù)形式的)授權(quán)、以及訪(fǎng)問(wèn)控制。
面向IoT SmartDevice這類(lèi)場(chǎng)景,業(yè)界就提的更少了,但在傳統(tǒng)企業(yè),尤其是工業(yè)企業(yè),傳感器、物理設(shè)備從工業(yè)控制協(xié)議向IP轉(zhuǎn)換,導(dǎo)致具備信息處理能力的「智能產(chǎn)品」在被客戶(hù)激活使用直至報(bào)廢過(guò)程中,信息的傳輸不能再基于VPN或者企業(yè)內(nèi)部專(zhuān)線(xiàn),導(dǎo)致物理鏈路上會(huì)存在一部分公網(wǎng)鏈路。此時(shí)的API GW所需要滿(mǎn)足的,就是不是前三種單向的由外而內(nèi)的數(shù)據(jù)流,也不是第四種由內(nèi)而外的數(shù)據(jù)流,「內(nèi)外兼修」的雙向數(shù)據(jù)流,對(duì)于企業(yè)的系統(tǒng)來(lái)說(shuō)終端設(shè)備很多情況下都不是直連網(wǎng)關(guān),而是進(jìn)過(guò)一個(gè)「客戶(hù)側(cè)」的集中網(wǎng)關(guān)在和企業(yè)的接入網(wǎng)關(guān)進(jìn)行通信。
InfoQ:在一個(gè)微服務(wù)架構(gòu)中,API網(wǎng)關(guān)會(huì)在架構(gòu)中的那一層?他主要的作用是什么?
王延炯:接續(xù)前一個(gè)話(huà)題,我把API GW分為了五類(lèi),對(duì)于當(dāng)前的企業(yè)而言被關(guān)注的是前三類(lèi)或者前四類(lèi)API GW。顯然,它們都會(huì)出現(xiàn)在企業(yè)系統(tǒng)的邊界上,也就是和企業(yè)外部交互的「獨(dú)木橋」上。
它們除了保證數(shù)據(jù)的交換之外,還需要實(shí)現(xiàn)對(duì)接入客戶(hù)端的身份認(rèn)證、防報(bào)文重放與防數(shù)據(jù)篡改、功能調(diào)用的業(yè)務(wù)鑒權(quán)、響應(yīng)數(shù)據(jù)的脫敏、流量與并發(fā)控制,甚至基于API調(diào)用的計(jì)量或者計(jì)費(fèi)。
InfoQ:你有研究過(guò)Netflix的API網(wǎng)關(guān)嗎?在實(shí)現(xiàn)方式上,你覺(jué)得他們的方式有什么巧妙之處嗎?
王延炯:Netflix 的API GW,主要是指Zuul, Netflix 將他們用于自己的三大場(chǎng)景: Website Service, API Service, Streaming Service。其中前兩個(gè)定位與我的前兩個(gè)分類(lèi):Web App, Mobile App比較類(lèi)似,第三個(gè)Streaming Service主要是netflix的核心視頻業(yè)務(wù)所形成的特有形態(tài)。
Netflix在Zuul的實(shí)現(xiàn)上,主要特色是:Filter的PRE ROUTING POST ERROR(PRPE 模型),以及采用Groovy腳本的Filter實(shí)現(xiàn)機(jī)制、采用Cassandra作為filter repository的機(jī)制。
Filter 以及 Filter的PRPE模型,是典型的「前正后反模型」的實(shí)現(xiàn),為集成的標(biāo)準(zhǔn)化做好了框架層面的鋪墊。
Netflix其實(shí)并沒(méi)有對(duì)API GW進(jìn)行深入的功能實(shí)現(xiàn)(或者說(shuō)面相業(yè)務(wù)友好的相關(guān)功能),整體上它只提供了一個(gè)技術(shù)框架、和一些標(biāo)準(zhǔn)的filter實(shí)例實(shí)現(xiàn),相信了解過(guò)filter chain原理的分布式中間件工程師也能搭出這樣的框架。這么做的原因,我認(rèn)為很大原因是API GW所扮演的角色是一個(gè)業(yè)務(wù)平臺(tái),而非技術(shù)平臺(tái),將行業(yè)特征很強(qiáng)的業(yè)務(wù)部分開(kāi)源,對(duì)于受眾意義也不是特別大。另外,除了Netflix Zuul,在商業(yè)產(chǎn)品上還有apigee公司所提供的方案,在輕量級(jí)開(kāi)源實(shí)現(xiàn)上還有基于Nginx的 kong ,kong其實(shí)提供了19個(gè)插件式的功能實(shí)現(xiàn),涵蓋的面主要在于安全、監(jiān)控等領(lǐng)域,但缺少對(duì)報(bào)文轉(zhuǎn)換的能力(為什么缺 也很顯而易見(jiàn)——避免產(chǎn)生業(yè)務(wù)場(chǎng)景的耦合,更通用)。
另外,還有基于TCP協(xié)議的GW,比如攜程無(wú)線(xiàn)應(yīng)用的后端實(shí)現(xiàn)有HTTP和TCP兩種,有興趣的讀者也可以深入關(guān)注。
InfoQ:在API網(wǎng)關(guān)的設(shè)計(jì)上,需要包含哪些要素?
王延炯:從三個(gè)方面說(shuō)吧,API網(wǎng)關(guān)本身以及API網(wǎng)關(guān)客戶(hù)端,還有配套的自助服務(wù)平臺(tái)。具體如下:
API GW本身
NIO接入,異步接出
流控與屏蔽
秘鑰交換
客戶(hù)端認(rèn)證與報(bào)文加解密
業(yè)務(wù)路由框架
報(bào)文轉(zhuǎn)換
HTTP DNS/ Direct IP
API GW 客戶(hù)端 SDK / Library
基本通信
秘鑰交換與Cache
身份認(rèn)證與報(bào)文加解密
配套的在線(xiàn)自助服務(wù)平臺(tái)
代碼生成
文檔生成
沙盒調(diào)測(cè)
InfoQ:在API網(wǎng)關(guān)的落地上,你有可行的方案嗎?在API網(wǎng)關(guān)的落地上,難點(diǎn)是什么?
王延炯:在我所服務(wù)過(guò)的阿里系、非電商互聯(lián)網(wǎng)公司里,內(nèi)部的分布式服務(wù)調(diào)用采用的是Dubbo,但移動(dòng)應(yīng)用是iOS和Android,基本上沒(méi)有PC Web端的客戶(hù)端,在這種條件下,API GW所承擔(dān)的一個(gè)重要角色就是報(bào)文轉(zhuǎn)換,并且是跨語(yǔ)言、跨運(yùn)行平臺(tái)的報(bào)文轉(zhuǎn)換。報(bào)文就是數(shù)據(jù),在跨平臺(tái)、跨語(yǔ)言的條件下,對(duì)于數(shù)據(jù)的描述——元數(shù)據(jù)——也就是類(lèi)定義,對(duì)于API GW的系統(tǒng)性挑戰(zhàn)是巨大的:傳輸時(shí),報(bào)文內(nèi)不能傳輸類(lèi)定義,跨語(yǔ)言的類(lèi)定義轉(zhuǎn)換、生成與加載。
API GW的落地技術(shù)基本貫通沒(méi)有太大的難度,但形成最佳的實(shí)踐,有一些外圍的前置條件,比如:
后端API粒度
能和原子業(yè)務(wù)能力找到映射最好,一定要避免「萬(wàn)能接口」的出現(xiàn)。
業(yè)務(wù)路由的實(shí)現(xiàn)和含報(bào)文轉(zhuǎn)換的API不停機(jī)發(fā)布
盡可能的在報(bào)文頭里面存放業(yè)務(wù)路由所需要的信息,避免對(duì)報(bào)文體進(jìn)行解析。
API GW上線(xiàn)后,面臨的很大問(wèn)題都是后端服務(wù)如何自助發(fā)布到外部,同時(shí)不能重啟網(wǎng)關(guān)服務(wù),以保障業(yè)務(wù)的連續(xù)。在此過(guò)程中,如果涉及到報(bào)文格式的轉(zhuǎn)換,那對(duì)API網(wǎng)關(guān)實(shí)現(xiàn)的技術(shù)要求比較高。如果讓網(wǎng)關(guān)完成報(bào)文轉(zhuǎn)換,第一種方案,網(wǎng)關(guān)需要知道報(bào)文的具體格式(也就是報(bào)文的元數(shù)據(jù),或者是類(lèi)定義),這部分要支持熱更新。第二種方案,需要客戶(hù)端在報(bào)文內(nèi)另外附加元數(shù)據(jù),網(wǎng)關(guān)通過(guò)運(yùn)行期加載元數(shù)據(jù)對(duì)報(bào)文進(jìn)行解析在進(jìn)行報(bào)文的轉(zhuǎn)換,這種方案性能不會(huì)很好。第三種方案,就是在運(yùn)行期首次報(bào)文轉(zhuǎn)換的時(shí)候,根據(jù)元數(shù)據(jù)生成報(bào)文轉(zhuǎn)換代碼并加載,這種方案對(duì)技術(shù)實(shí)現(xiàn)要求比較高,對(duì)網(wǎng)關(guān)外圍平臺(tái)支撐力度要求也不低。
客戶(hù)端的秘鑰管理
很多人都會(huì)把安全問(wèn)題簡(jiǎn)單的用加密算法來(lái)解決,這是一個(gè)嚴(yán)重的誤區(qū),很多時(shí)候都存在對(duì)秘鑰進(jìn)行系統(tǒng)性管理的短板。打個(gè)比方,加密算法就好比家里的保險(xiǎn)箱,而秘鑰是保險(xiǎn)箱的鑰匙,而缺乏秘鑰管理的安全方案,就好比把鑰匙放在自家的客廳茶幾上。更何況,安全方案里加解密也只是其中的一部分。
InfoQ:你認(rèn)為一個(gè)設(shè)計(jì)良好的API網(wǎng)關(guān)應(yīng)該做到什么?
王延炯:目前業(yè)界關(guān)注的API GW,主要是在前三類(lèi),下文對(duì)于API網(wǎng)關(guān)的設(shè)計(jì)上,側(cè)重于「面向接入」的API GW。
在API網(wǎng)關(guān)的設(shè)計(jì)上,僅僅有類(lèi)似Zuul這樣的「面向接入」的運(yùn)行期框架是遠(yuǎn)遠(yuǎn)不夠的,因?yàn)橐粋€(gè)完整的、「面向接入」的API GW需要包含以下功能:
面向運(yùn)行期
對(duì)客戶(hù)端實(shí)現(xiàn)身份認(rèn)證
通信會(huì)話(huà)的秘鑰協(xié)商,報(bào)文的加密與解密
日常流控與應(yīng)急屏蔽
內(nèi)部響應(yīng)報(bào)文的場(chǎng)景化裁剪
支持「前正后反模型」的集成框架
報(bào)文格式的轉(zhuǎn)換
業(yè)務(wù)路由的支撐
客戶(hù)端優(yōu)先的超時(shí)機(jī)制
全局流水號(hào)的生成與應(yīng)用
面向客戶(hù)端支持HTTP DNS / Direct IP
面向開(kāi)發(fā)期
自助的沙盒測(cè)試環(huán)境
面向客戶(hù)端友好的 SDK / Library以及示例
能夠根據(jù)后端代碼直接生成客戶(hù)端業(yè)務(wù)代碼框架
完善的報(bào)文描述能力(元數(shù)據(jù)),支撐配置型的報(bào)文裁剪
面向運(yùn)維與運(yùn)營(yíng)
支持面向接入方的獨(dú)立部署與快速水平擴(kuò)展
面向業(yè)務(wù)場(chǎng)景或合作伙伴的自助API開(kāi)通
對(duì)外接口性能與線(xiàn)上環(huán)境故障定位自助平臺(tái)