微信截圖_17363901826052.png)
API 設(shè)計原理:從理論到實踐
隨著微服務(wù)的大紅大紫,大家紛紛使用微服務(wù)架構(gòu)來實現(xiàn)新系統(tǒng)或進行老系統(tǒng)的改造。當然,微服務(wù)帶給我們太多的好處,同時也帶給我們許多的問題需要解決。采用微服務(wù)后,所有的服務(wù)都變成了一個個細小的API,那么這些服務(wù)API該怎么正確的管理?API認證授權(quán)如何實現(xiàn)?如何實現(xiàn)服務(wù)的負載均衡,熔斷,灰度發(fā)布,限流流控?如何合理的治理這些API服務(wù)尤其重要。在微服務(wù)架構(gòu)中,API Gateway作為整體架構(gòu)的重要組件,它抽象了微服務(wù)中都需要的公共功能,同時提供了客戶端負載均衡,服務(wù)自動熔斷,灰度發(fā)布,統(tǒng)一認證,限流流控,日志統(tǒng)計等豐富的功能,幫助我們解決很多API管理難題。
目錄:
一、什么是API Gateway
二、為什么需要API Gateway
三、API Gateway中一些重要的功能
四、API Gateway vs 反向代理
五、API Gateway對API的認證及鑒權(quán)
六、采用OAuth2方式認證的兩種部署方式
七、總結(jié)
(圖片來自網(wǎng)絡(luò))
這張圖,非常形象的解釋了API Gateway和微服務(wù)的關(guān)系。做為聽眾,我們只想聽到美妙動人的音樂旋律,完全不會在乎音樂是怎么演奏的。而指揮家則根據(jù)曲譜負責(zé)指揮好每一個演奏者,使每一個演奏者之間配合默契,共同完成這場音樂演出。在微服務(wù)的世界里,API Gateway就如同一位指揮家,“指揮”著不同的“演奏人”(微服務(wù))。
我們知道在微服務(wù)架構(gòu)中,大型服務(wù)都被拆分成了獨立的微服務(wù),每個微服務(wù)通常會以RESTFUL API的形式對外提供服務(wù)。但是在UI方面,我們可能需要在一個頁面上顯示來自不同微服務(wù)的數(shù)據(jù),此時就會需要一個統(tǒng)一的入口來進行API的調(diào)用。上圖中我們可以看到,API Gateway就在此場景下充當了多個服務(wù)的大門,系統(tǒng)的統(tǒng)一入口,從面向?qū)ο笤O(shè)計的角度看,它與外觀模式類似,API Gateway封裝了系統(tǒng)的內(nèi)部復(fù)雜結(jié)構(gòu),同時它還可能具有其他API管理/調(diào)用的通用功能,如認證,限流,流控等功能。
首先,Chris Richardson在http://microservices.io/中也提及到,在微服務(wù)的架構(gòu)模式下,API Gateway是微服務(wù)架構(gòu)中一個非常通用的模式,利用API Gateway可以解決調(diào)用方如何調(diào)用獨立的微服務(wù)這個問題。
從部署結(jié)構(gòu)上說,上圖是不采用API Gateway的微服務(wù)部署模式,我們可以清晰看到,這種部署模式下,客戶端與負載均衡器直接交互,完成服務(wù)的調(diào)用。但這是這種模式下,也有它的不足。
上圖為采用API Gateway模式,我們通過上圖可以看到,API Gateway做為系統(tǒng)統(tǒng)一入口,實現(xiàn)了對各個微服務(wù)間的整合,同時又做到了對客戶端友好,屏蔽系統(tǒng)了復(fù)雜性和差異性。對比之前無API Gateway模式,API Gateway具有幾個比較重要的優(yōu)點:
下面我們用圖來說明API Gateway中一些重要的功能:
在實際的部署應(yīng)用中,當應(yīng)用系統(tǒng)面臨大量訪問,負載過高時,通常我們會增加服務(wù)數(shù)量來進行橫向擴展,使用集群來提高系統(tǒng)的處理能力。此時多個服務(wù)通過某種負載算法分攤了系統(tǒng)的壓力,我們將這種多節(jié)點分攤壓力的行為稱為負載均衡。
API Gateway可以幫助我們輕松的實現(xiàn)負載均衡,利用服務(wù)發(fā)現(xiàn)知道所有Service的地址和位置,通過在API Gateway中實現(xiàn)負載均衡算法,就可以實現(xiàn)負載均衡效果。
在實際生產(chǎn)中,一些服務(wù)很有可能因為某些原因發(fā)生故障,如果此時不采取一些手段,會導(dǎo)致整個系統(tǒng)“雪崩”?;蛞蛳到y(tǒng)整體負載的考慮,會對服務(wù)訪問次數(shù)進行限制。服務(wù)熔斷、服務(wù)降級就是解決上述問題的主要方式。API Gateway可以幫助我們實現(xiàn)這些功能,對于服務(wù)的調(diào)用次數(shù)的限制,當某服務(wù)達到上限時,API Gateway會自動停止向上游服務(wù)發(fā)送請求,并像客戶端返回錯誤提示信息或一個統(tǒng)一的響應(yīng),進行服務(wù)降級。對于需要臨時發(fā)生故障的服務(wù),API Gateway自動可以打開對應(yīng)服務(wù)的斷路器,進行服務(wù)熔斷,防止整個系統(tǒng)“雪崩”。
服務(wù)發(fā)布上線過程中,我們不可能將新版本全部部署在生產(chǎn)環(huán)節(jié)中,因為新版本并沒有接受真實用戶、真實數(shù)據(jù)、真實環(huán)境的考驗,此時我們需要進行灰度發(fā)布,灰度發(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始灰度的時候就可以發(fā)現(xiàn)、調(diào)整問題,同時影響小。API Gateway可以幫助我們輕松的完成灰度發(fā)布,只需要在API Gateway中配置我們需要的規(guī)則,按版本,按IP段等,API Gateway會自動為我們完成實際的請求分流。
在傳統(tǒng)部署架構(gòu)中,反向代理,大多是用于多個系統(tǒng)模塊間的聚合,實現(xiàn)負載均衡,外網(wǎng)向內(nèi)網(wǎng)的轉(zhuǎn)發(fā)。通過修改配置文件的方式來進行增加或刪除節(jié)點,并重啟服務(wù)才可生效。通常來說,反向代理服務(wù)器只具備負載均衡、轉(zhuǎn)發(fā)基本功能,若要需要其他功能,需要增加擴展或提供腳本來實現(xiàn)。
在API Gateway部署模式中,API Gateway可以看作特殊的反向代理,是對反向代理服務(wù)器功能的擴充,同時API Gateway僅局限于服務(wù)API層面,對API做進一步的管理,保護。API Gateway不僅提供了負載均衡,轉(zhuǎn)發(fā)功能,還提供了灰度發(fā)布,統(tǒng)一認證,熔斷,消息轉(zhuǎn)換,訪問日志等豐富的功能。
倘若我們實際運用中,不需要服務(wù)發(fā)現(xiàn),服務(wù)動態(tài)擴容,服務(wù)熔斷,統(tǒng)一認證,消息轉(zhuǎn)換等一系列API Gateway功能,我們完全可以使用反向代理服務(wù)器來部署微服務(wù)架構(gòu),當然如果這樣做,如遇到增加或減少服務(wù)節(jié)點時,需要修改反向代理服務(wù)器配置,重啟服務(wù)才可以生效。而當我們可能不僅僅需要負載均衡,內(nèi)外網(wǎng)轉(zhuǎn)發(fā),還需要其他功能,又同時想實現(xiàn)一些各服務(wù)都需要的通用的功能時,這時候就改考慮API Gateway了。
認證及鑒權(quán)
目前在微服務(wù)中,我們還需要考慮如何保護我們的API只能被同意授權(quán)的客戶調(diào)用。那么對于API的保護,目前大多數(shù)采用的方式有這么幾種,分別為AppKeys,OAuth2 和 OAuth2+JWT,接下來我們逐個了解下。
目前采用AppKeys Auth認證的公有云API Gateway和數(shù)據(jù)開放平臺居多,如阿里API Gateway,聚合數(shù)據(jù)等,這種認證模式是由API Gateway頒發(fā)一個key,或者appkey+appsecret+某種復(fù)雜的加密算法生成AppKey,調(diào)用方獲取到key后直接調(diào)用API。這個key可以是無任何意義的一串字符。API Gateway在收到調(diào)用API請求時,首先校驗key的合法性,包括key是否失效,當前調(diào)用API是否被訂閱等等信息,若校驗成功,則請求上游服務(wù),返回結(jié)果。此處上游服務(wù)不再對請求做任何校驗,直接返回結(jié)果。采用AppKeys認證模式比較適合Open Service的場景。其中并不涉及到用戶信息,權(quán)限信息。
大部分場景中,我們還是需要有知道誰在調(diào)用,調(diào)用者是否有對應(yīng)的角色權(quán)限等。OAuth2可以幫助我們來完成這個工作。在OAuth2的世界中,分為以下幾種角色:Resource Owner,Client,Authorization Server,Resource Sever。上圖是一個簡單的OAuh2流程來說明各個角色之前的關(guān)系。最終,App獲得了Rory的個人信息。
OAuth2 + JWT流程跟OAuth2完全一致。了解OAuth2的童鞋都應(yīng)該知道,OAuth2最后會給調(diào)用方頒發(fā)一個Access Token,OAuth2+JWT實際上就是將Access Token換成JWT而已。這樣做的好處僅僅是減少Token校驗時查詢DB的次數(shù)。
有那么多認證方式,加入了API Gateway后,該怎么做呢?在微服務(wù)的世界中,我們每個服務(wù)可能都會需要用戶信息,用戶權(quán)限來判斷當前接口或功能是否對當前用戶可用。
我們可以將統(tǒng)一認證放在API Gateway來實現(xiàn),由API Gateway來做統(tǒng)一的攔截和鑒權(quán),結(jié)合上文所描述的認證方式中,OAuth2協(xié)議中可以攜帶用戶信息,故采用OAuth2。
兩種部署方式
第一種,微服務(wù)部署在單獨的VPC網(wǎng)絡(luò)中,同時微服務(wù)互相授信,互相調(diào)用不需要驗證請求是否合法。這種模式下,當調(diào)用請求經(jīng)過API Gateway時,API Gateway會拿著調(diào)用者提供的Access Token到Authorization Server中認證,若Access Token合法,Authorization Server會返回當前Access Token所代表的基本信息,API Gateway獲取到這些基本信息后,會將這些信息放置在自定義Header中請求上游服務(wù),上游服務(wù)可獲取這些基本信息來進行對應(yīng)操作的權(quán)限判斷。如果我們對API Gateway跟Authorization Server驗證Access token的過程中,擔(dān)心有性能和效率損失,我們可以將Access Token改為JWT token,由API Gateway持有公鑰對JWT token進行解密,減少一次HTTP請求。但是這種做法不推薦,畢竟JWT基本信息是Base64的,可以被輕而易舉的解密。
第二種,微服務(wù)互相不授信,彼此調(diào)用需要驗證請求的合法性,這種模式為了更加安全,我們需要內(nèi)外token轉(zhuǎn)換。首先,調(diào)用方通過OAuth2流程,獲取到Access Token,當前Access Token是一串沒有意義的字符串,我們將它稱為Reference Token。當調(diào)用方調(diào)用API時,此時API Gateway會拿著調(diào)用者提供的Access Token到Authorization Server中認證置換。此時,Authorization Server不會返回基本信息,而是返回一個包含基本信息的JWT Token,我們將它稱為ID Token。緊接著API Gateway會將JWT Token放到Request Header中,請求上游服務(wù)。上游服務(wù)獲取到當前JWT token后,會請求Authorization Server獲取到JWK,利用JWK對當前JWT Token進行校驗,解密,最后,進行角色權(quán)限判斷。微服務(wù)之間的互相調(diào)用,也必須將JWT Token放在Request Header中。
總結(jié)來說,以上幾種方式都可以完成認證,但具體采用什么方式認證,還是取決于實際中對系統(tǒng)安全性的要求和具體的業(yè)務(wù)場景。
API Gateway在微服務(wù)架構(gòu)中起到了至關(guān)重要的作用。在文章中我們介紹了什么是API Gateway以及為什么需要API Gateway。API Gateway它作為微服務(wù)系統(tǒng)的大門,向我們提供了請求轉(zhuǎn)發(fā),服務(wù)熔斷,限流流控等公共功能,它又統(tǒng)一整合了各個微服務(wù),對外屏蔽了系統(tǒng)的復(fù)雜性和差異性。
另外,我們介紹了目前微服務(wù)架構(gòu)中幾種認證方案。結(jié)合API Gateway,我們采用了OAuth2協(xié)議對API進行認證鑒權(quán),同時又從在部署架構(gòu)的角度上,介紹了兩種不一樣的認證方式。
本文章轉(zhuǎn)載微信公眾號@EAWorld