1. 程式人生 > >API管理的正確姿勢--API Gateway

API管理的正確姿勢--API Gateway

API閘道器的功能、鑑權及OAuth2認證的部署方式。

轉載本文需註明出處:微信公眾號EAWorld,違者必究。

編者按:

數字化生態,以創新客戶體驗為核心,所有我們身邊能感知到的變化都來自於漸近的創新。這些創新需要試錯,需要不斷的升級,並且創新往往與我們熟知的功能分離開來分別呈現。微服務對於傳統單體架構的優勢之一就在於,服務的拆分帶來了更新、部署、管理的隔離性,讓一些單獨的服務可以進行創新和實驗。從而支撐了使用者體驗的不斷升級,為實現企業數字化轉型的過程,提供了技術架構層面的支撐。

我們現在已經可以很方便的通過一些電子商城購買運營的合約機,而無需到營業廳親自辦理相關的業務,這就是API Gateway的一種底層支撐。由於運營商通過API Gateway向第三方的商務平臺開放了與套餐、機型銷售等服務,並通過流控、鑑權等機制保障相關的安全性,才使得這樣方便流暢的購物體驗得以實現。

對於MOBA手遊類玩家來說,“王者榮耀”是一款頗受歡迎的遊戲。在一些場景下,我們會感知到“不停機更新”“體驗服更新”這兩種不同方式的更新形態,在底層,就是API Gateway或者類似技術的實現,支撐灰度釋出,讓一些新特性發布給體驗服(比如傳說中露娜的二技能變化,僅在體驗服更新,實際上並未如傳說中一樣在S11賽季更新到正式服),或者特定的遊戲使用者,待功能完善或者穩定執行,再向正式服或者全部使用者釋出,讓遊戲玩家的體驗可以更加流暢,甚至是無感知的升級。

這些只是微服務架構或者API Gateway所支撐的萬千業務場景中的滄海一粟。

但微服務本身也會帶來諸多問題,粒度小難以管理就是其中之一,本文即從這個角度,闡述了API Gateway所起到的作用和一些關鍵的技術要素。

以微服務為核心的分散式框架貫穿了普元數字化企業技術平臺的APaaS層面,本文所介紹的API Gateway是其中的關鍵組成部分(圖中標黃的部分)。

引言:

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

目錄:

一、什麼是API Gateway

二、為什麼需要API Gateway

三、API Gateway中一些重要的功能

四、API Gateway vs 反向代理

五、API Gateway對API的認證及鑑權

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

七、總結

一、什麼是API Gateway

(圖片來自網路)

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

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

二、為什麼需要API Gateway

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

從部署結構上說,上圖是不採用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可以幫助我們輕鬆的實現負載均衡,利用服務發現知道所有Service的地址和位置,通過在API Gateway中實現負載均衡演算法,就可以實現負載均衡效果。

服務熔斷

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

灰度釋出

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

四、API Gateway vs 反向代理

反向代理

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

API Gateway

在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

目前採用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

大部分場景中,我們還是需要有知道誰在呼叫,呼叫者是否有對應的角色許可權等。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 Gateway來實現,由API Gateway來做統一的攔截和鑑權,結合上文所描述的認證方式中,OAuth2協議中可以攜帶使用者資訊,故採用OAuth2。

六、採用OAuth2方式認證的

兩種部署方式

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

第一種,微服務部署在單獨的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中

第二種,微服務互相不授信,彼此呼叫需要驗證請求的合法性,這種模式為了更加安全,我們需要內外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進行認證鑑權,同時又從在部署架構的角度上,介紹了兩種不一樣的認證方式。

精選提問:

問1:springcloud 用哪個元件?

答:由於基於SpringBoot2的Spring cloud F版還未release,現階段springcloud GA版本使用Zuul。

不過,待Spring cloud F版GA後,建議多關注下Spring Cloud Gateway。它是spring團隊基於netty重寫的API Gateway元件,相對於Zuul效能較好

問2:微服務都是在spring cloud系列下 用springcloud自帶的zuul還是選擇其他的好?

答:如果基於Spring cloud的話,還是建議使用Spring cloud自帶的Zuul,能大量減少我們對spring cloud體系下微服務治理方案的整合時間。

問3:Zuul 是 spring cloud 的apigetway 元件嗎?

答:目前,spring cloud GA版(最新為Edgware)的API Gateway元件為Zuul。

但即將GA的F版,Spring團隊使用netty自己實現了API Gateway對外提供,若使用F版,我們就可以進行選擇,zuul和spring cloud gateway都可以。

問4:微服務呼叫系統外部服務 是否也要走Api gateway?

答:如果類似APIGateway上可以直接做編排的,那確實呼叫外部服務的某些時候,可以直接從API gateway走,但是 API gateway本身的切面是對外提供服務,具體還是要要看業務場景。

問5:最後一種不授信,是否意味著微服務只信任自己親自從auth Server拿到的使用者資訊?

答:沒錯,最後一種情況下,微服務都要對請求進行校驗。這裡需要說明下,不是微服務從auth server獲取使用者資訊,而是微服務從auth sever獲取jwk,通過jwk解密請求中JWT來獲取資訊,進行使用者資訊許可權校驗。

問6:api gateway 修改釋出的問題,有什麼好方法嗎?整個系統的瓶頸都集中在了apiGateway

回答:API Gateway也是一個微服務,微服務最大的特性就是可以伸縮,叢集,高可用,系統遇到瓶頸可以增加節點。我曾經參與的專案中,最終上線使用者達到9萬之多,此時我們也只使用了2個API Gateway的節點。

問7:用spring cloud的話,是不是可以用zuul整合spring cloud oauth2認證授權中心服務,所有涉及獲取token、重新整理token、校驗token的操作都在zuul上處理,後端業務服務不與認證授權中心做任何耦合呢?另外,有沒有現有的比較好的api gateway整合UAA服務的專案或產品可參考呢?

答:目前,spring cloud oauth2只提供了oauth2的幾種授權模式的基本實現,我們還是得根據自己的實際業務邏輯,進行定製化。如果將所有的Token的操作放在zuul上處理是可以的,如剛才ppt講的第一種安全認證方式。目前據我瞭解的,沒有什麼好的例子夠我們參考。

問8:認證伺服器賬號資訊應該放在認證伺服器,還是放在業務裡呢?

答:建議將使用者賬戶資訊放在認證伺服器中,成為單獨服務,與業務解耦。

問9:請問,oauth2 認證後 使用者資訊 是放在token 中加密好,還是單獨提供介面查詢好?

回答:兩種方式都可以,一切還是看我們系統的具體實際業務需求。

問10:如何跟業務資料同步呢?比如你註冊個賬號,我們可能給他送1000塊錢。這1000塊錢存在單獨的業務伺服器。我們肯定是非同步的吧,怎麼保證訊息處理的實時性啊。

回答:業務資訊跟使用者賬戶是有一個對映關係儲存的,儲存在業務中。我剛所說的使用者賬戶資訊管理,只涉及到使用者基本資訊,組織機構等等不涉及業務的資訊。

關於作者:高士皓,普元SOA&雲端計算部門高階軟體工程師,現主要從事普元API Gateway開發設計工作。曾在Tibco、海航科技技術研究院擔任高階軟體工程師。在海航任職期間,參與海航數字化轉型建設,帶領團隊設計開發海航API Gateway,海航統一登入平臺等專案。