06.22 「系統架構」API Gateway——API管理的正確姿勢

引言

隨著微服務的大紅大紫,大家紛紛使用微服務架構來實現新系統或進行老系統的改造。當然,微服務帶給我們太多的好處,同時也帶給我們許多的問題需要解決。採用微服務後,所有的服務都變成了一個個細小的API,那麼這些服務API該怎麼正確的管理?API認證授權如何實現?如何實現服務的負載均衡,熔斷,灰度發佈,限流流控?如何合理的治理這些API服務尤其重要。在微服務架構中,API Gateway作為整體架構的重要組件,它抽象了微服務中都需要的公共功能,同時提供了客戶端負載均衡,服務自動熔斷,灰度發佈,統一認證,限流流控,日誌統計等豐富的功能,幫助我們解決很多API管理難題。

什麼是API Gateway

「系統架構」API Gateway——API管理的正確姿勢

這張圖,非常形象的解釋了API Gateway和微服務的關係。做為聽眾,我們只想聽到美妙動人的音樂旋律,完全不會在乎音樂是怎麼演奏的。而指揮家則根據曲譜負責指揮好每一個演奏者,使每一個演奏者之間配合默契,共同完成這場音樂演出。在微服務的世界裡,API Gateway就如同一位指揮家,“指揮”著不同的“演奏人”(微服務)。

「系統架構」API Gateway——API管理的正確姿勢

我們知道在微服務架構中,大型服務都被拆分成了獨立的微服務,每個微服務通常會以RESTFUL API的形式對外提供服務。但是在UI方面,我們可能需要在一個頁面上顯示來自不同微服務的數據,此時就會需要一個統一的入口來進行API的調用。上圖中我們可以看到,API Gateway就在此場景下充當了多個服務的大門,系統的統一入口,從面向對象設計的角度看,它與外觀模式類似,API Gateway封裝了系統的內部複雜結構,同時它還可能具有其他API管理/調用的通用功能,如認證,限流,流控等功能。

為什麼需要API Gateway

「系統架構」API Gateway——API管理的正確姿勢

首先,Chris Richardson在http://microservices.io/中也提及到,在微服務的架構模式下,API Gateway是微服務架構中一個非常通用的模式,利用API Gateway可以解決調用方如何調用獨立的微服務這個問題。

「系統架構」API Gateway——API管理的正確姿勢

從部署結構上說,上圖是不採用API Gateway的微服務部署模式,我們可以清晰看到,這種部署模式下,客戶端與負載均衡器直接交互,完成服務的調用。但這是這種模式下,也有它的不足。

  • 不支持動態擴展,系統每多一個服務,就需要部署或修改負載均衡器。
  • 無法做到動態的開關服務,若要下線某個服務,需要運維人員將服務地址從負載均衡器中移除。
  • 對於API的限流,安全等控制,需要每個微服務去自己實現,增加了微服務的複雜性,同時也違反了微服務設計的單一職責原則。
「系統架構」API Gateway——API管理的正確姿勢

上圖為採用API Gateway模式,我們通過上圖可以看到,API Gateway做為系統統一入口,實現了對各個微服務間的整合,同時又做到了對客戶端友好,屏蔽系統了複雜性和差異性。對比之前無API Gateway模式,API Gateway具有幾個比較重要的優點:

  • 採用API Gateway可以與微服務註冊中心連接,實現微服務無感知動態擴容。
  • API Gateway對於無法訪問的服務,可以做到自動熔斷,無需人工參與。
  • API Gateway可以方便的實現藍綠部署,金絲雀發佈或A/B發佈。
  • API Gateway做為系統統一入口,我們可以將各個微服務公共功能放在API Gateway中實現,以儘可能減少各服務的職責。
  • 幫助我們實現客戶端的負載均衡策略。

API Gateway中一些重要的功能

下面我們用圖來說明API Gateway中一些重要的功能:

負載均衡

「系統架構」API Gateway——API管理的正確姿勢

在實際的部署應用中,當應用系統面臨大量訪問,負載過高時,通常我們會增加服務數量來進行橫向擴展,使用集群來提高系統的處理能力。此時多個服務通過某種負載算法分攤了系統的壓力,我們將這種多節點分攤壓力的行為稱為負載均衡。

API Gateway可以幫助我們輕鬆的實現負載均衡,利用服務發現知道所有Service的地址和位置,通過在API Gateway中實現負載均衡算法,就可以實現負載均衡效果。

服務熔斷

「系統架構」API Gateway——API管理的正確姿勢

在實際生產中,一些服務很有可能因為某些原因發生故障,如果此時不採取一些手段,會導致整個系統“雪崩”。或因系統整體負載的考慮,會對服務訪問次數進行限制。服務熔斷、服務降級就是解決上述問題的主要方式。API Gateway可以幫助我們實現這些功能,對於服務的調用次數的限制,當某服務達到上限時,API Gateway會自動停止向上遊服務發送請求,並像客戶端返回錯誤提示信息或一個統一的響應,進行服務降級。對於需要臨時發生故障的服務,API Gateway自動可以打開對應服務的斷路器,進行服務熔斷,防止整個系統“雪崩”。

灰度發佈

「系統架構」API Gateway——API管理的正確姿勢

服務發佈上線過程中,我們不可能將新版本全部部署在生產環節中,因為新版本並沒有接受真實用戶、真實數據、真實環境的考驗,此時我們需要進行灰度發佈,灰度發佈可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,同時影響小。API Gateway可以幫助我們輕鬆的完成灰度發佈,只需要在API Gateway中配置我們需要的規則,按版本,按IP段等,API Gateway會自動為我們完成實際的請求分流。

API Gateway vs 反向代理

反向代理

「系統架構」API Gateway——API管理的正確姿勢

在傳統部署架構中,反向代理,大多是用於多個系統模塊間的聚合,實現負載均衡,外網向內網的轉發。通過修改配置文件的方式來進行增加或刪除節點,並重啟服務才可生效。通常來說,反向代理服務器只具備負載均衡、轉發基本功能,若要需要其他功能,需要增加擴展或提供腳本來實現。

API Gateway

「系統架構」API Gateway——API管理的正確姿勢

在API Gateway部署模式中,API Gateway可以看作特殊的反向代理,是對反向代理服務器功能的擴充,同時API Gateway僅侷限於服務API層面,對API做進一步的管理,保護。API Gateway不僅提供了負載均衡,轉發功能,還提供了灰度發佈,統一認證,熔斷,消息轉換,訪問日誌等豐富的功能。

如何選擇?

倘若我們實際運用中,不需要服務發現,服務動態擴容,服務熔斷,統一認證,消息轉換等一系列API Gateway功能,我們完全可以使用反向代理服務器來部署微服務架構,當然如果這樣做,如遇到增加或減少服務節點時,需要修改反向代理服務器配置,重啟服務才可以生效。而當我們可能不僅僅需要負載均衡,內外網轉發,還需要其他功能,又同時想實現一些各服務都需要的通用的功能時,這時候就改考慮API Gateway了。

API Gateway對API的認證及鑑權

目前在微服務中,我們還需要考慮如何保護我們的API只能被同意授權的客戶調用。那麼對於API的保護,目前大多數採用的方式有這麼幾種,分別為AppKeys,OAuth2 和 OAuth2+JWT,接下來我們逐個瞭解下。

認證方式

1)AppKeys

「系統架構」API Gateway——API管理的正確姿勢

目前採用AppKeys Auth認證的公有云API Gateway和數據開放平臺居多,如阿里API Gateway,聚合數據等,這種認證模式是由API Gateway頒發一個key,或者appkey+appsecret+某種複雜的加密算法生成AppKey,調用方獲取到key後直接調用API。這個key可以是無任何意義的一串字符。API Gateway在收到調用API請求時,首先校驗key的合法性,包括key是否失效,當前調用API是否被訂閱等等信息,若校驗成功,則請求上游服務,返回結果。此處上游服務不再對請求做任何校驗,直接返回結果。採用AppKeys認證模式比較適合Open Service的場景。其中並不涉及到用戶信息,權限信息。

2)OAuth2

「系統架構」API Gateway——API管理的正確姿勢

大部分場景中,我們還是需要有知道誰在調用,調用者是否有對應的角色權限等。OAuth2可以幫助我們來完成這個工作。在OAuth2的世界中,分為以下幾種角色:Resource Owner,Client,Authorization Server,Resource Sever。上圖是一個簡單的OAuh2流程來說明各個角色之前的關係。最終,App獲得了Rory的個人信息。

3)OAuth2+JWT

OAuth2 + JWT流程跟OAuth2完全一致。瞭解OAuth2的童鞋都應該知道,OAuth2最後會給調用方頒發一個Access Token,OAuth2+JWT實際上就是將Access Token換成JWT而已。這樣做的好處僅僅是減少Token校驗時查詢DB的次數。

OAuth2 with API Gateway

「系統架構」API Gateway——API管理的正確姿勢

有那麼多認證方式,加入了API Gateway後,該怎麼做呢?在微服務的世界中,我們每個服務可能都會需要用戶信息,用戶權限來判斷當前接口或功能是否對當前用戶可用。

我們可以將統一認證放在API Gateway來實現,由API Gateway來做統一的攔截和鑑權,結合上文所描述的認證方式中,OAuth2協議中可以攜帶用戶信息,故採用OAuth2。

採用OAuth2方式認證的兩種部署方式

VPC網絡部署,服務內部授信

「系統架構」API Gateway——API管理的正確姿勢

第一種,微服務部署在單獨的VPC網絡中,同時微服務互相授信,互相調用不需要驗證請求是否合法。這種模式下,當調用請求經過API Gateway時,API Gateway會拿著調用者提供的Access Token到Authorization Server中認證,若Access Token合法,Authorization Server會返回當前Access Token所代表的基本信息,API Gateway獲取到這些基本信息後,會將這些信息放置在自定義Header中請求上游服務,上游服務可獲取這些基本信息來進行對應操作的權限判斷。如果我們對API Gateway跟Authorization Server驗證Access token的過程中,擔心有性能和效率損失,我們可以將Access Token改為JWT token,由API Gateway持有公鑰對JWT token進行解密,減少一次HTTP請求。但是這種做法不推薦,畢竟JWT基本信息是Base64的,可以被輕而易舉的解密。

微服務互相不授信,不在VPC中

「系統架構」API Gateway——API管理的正確姿勢

第二種,微服務互相不授信,彼此調用需要驗證請求的合法性,這種模式為了更加安全,我們需要內外token轉換。首先,調用方通過OAuth2流程,獲取到Access Token,當前Access Token是一串沒有意義的字符串,我們將它稱為Reference Token。當調用方調用API時,此時API Gateway會拿著調用者提供的Access Token到Authorization Server中認證置換。此時,Authorization Server不會返回基本信息,而是返回一個包含基本信息的JWT Token,我們將它稱為ID Token。緊接著API Gateway會將JWT Token放到Request Header中,請求上游服務。上游服務獲取到當前JWT token後,會請求Authorization Server獲取到JWK,利用JWK對當前JWT Token進行校驗,解密,最後,進行角色權限判斷。微服務之間的互相調用,也必須將JWT Token放在Request Header中。

總結來說,以上幾種方式都可以完成認證,但具體採用什麼方式認證,還是取決於實際中對系統安全性的要求和具體的業務場景。

總結

API Gateway在微服務架構中起到了至關重要的作用。在文章中我們介紹了什麼是API Gateway以及為什麼需要API Gateway。API Gateway它作為微服務系統的大門,向我們提供了請求轉發,服務熔斷,限流流控等公共功能,它又統一整合了各個微服務,對外屏蔽了系統的複雜性和差異性。

另外,我們介紹了目前微服務架構中幾種認證方案。結合API Gateway,我們採用了OAuth2協議對API進行認證鑑權,同時又從在部署架構的角度上,介紹了兩種不一樣的認證方式。



分享到:


相關文章: