天天看點

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

阿裡妹導讀:API 是子產品或者子系統之間互動的接口定義。好的系統架構離不開好的 API 設計,而一個設計不夠完善的 API 則注定會導緻系統的後續發展和維護非常困難。比較好的API設計樣闆可以參考 github 和 k8s ,它們都是典型的RESTful接口。雲服務對外開放的視窗就是OpenAPI,今天要讨論的話題是“雲服務場景下OpenAPI設計的挑戰”。

為什麼要有API規範

之是以強調“雲服務”的原因在于,小規模獨立API的設計與大規模批量生産API面臨的問題是不一樣的。同樣,隻專注于自身産品API的可用性與從更高的層次去看雲服務整體API體系的健壯性,要建設的體系也是不一樣的。

例如,做一個WEB頁面使用的API,隻需要考慮性能、穩定性、鑒權就好,因為頁面與API是一體的,可以一起釋出和復原,隻要功能正常,即便API設計有缺陷,使用者也可以接受。而雲服務要開放API考慮問題就多了:

  • 首先,雲服務開放的是基礎設施和服務接口,一般是系統級的對接,API一旦開放想要變更就非常困難;
  • 其次,雲服務并非單獨運作,不同的産品實際場景中是互相組合的,需考慮産品間的一緻性和互通便利性;
  • 雲服務API數量龐大,為了更友善使用,配套的API查找、編排、自動化生成SDK等需求也比普通服務強烈;
  • 雲服務的穩定性非常重要,核心産品的穩定性就是客戶的生命線,要求非常高。

是以雲服務由于産品線衆多,需要統一的API規範來保證雲産品間API體驗一緻,在底層平台層面互相相容,便于上層應用平台化,同時要兼顧到圍繞公有雲服務的第三方生态、開源生态、企業生态。

在具體規範層面,業界也在不斷嘗試,比較知名的是OpenAPI Specfication和 Google API Design Guide。前者針對RESTful API設計在細節層面給出了非常具體的規定,已經成為RESTful API設計領域的事實标準,而後者則主要從雲廠商的角度提出許多最佳實踐性質的規範與建議,這些原則不僅僅适用于RESTful API,也适合其他類型API設計。對API設計感興趣的開發者,可以詳細研究一下資料。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

2018年Openapi Specification釋出了3.0版本

圖檔來源:

https://swagger.io/

是以,對于雲服務商來說,在關鍵環節制定明确的API規範有助于雲服務對内提高産品間互通的效率,對外提供一緻的使用體驗,有助于雲服務更好地被內建。那麼要做好雲服務的橫向規範會碰到哪些困難呢?本文就從實踐中總結了7大挑戰。

挑戰1:選擇API設計模式

當你在考慮單個産品的API表現形式時,首先會選擇一種具體的API風格,常見的有RPC(Remote Procedure Call)和ROA(the Rest-Oriented Architecture)兩種模式,然後針對複雜的資料結構你會考慮使用什麼樣的序列化協定,常見的包括Json/Xml/WSDL/Hessian等,用于封裝傳輸資料。但涉及到不同的産品時,在具體選型時考慮的問題可能就不太一樣了。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

gRPC示意圖

https://www.grpc.io/docs/guides/

雖然RESTful設計風格曝光率很高,但并不是所有雲服務商都選擇了完全遵循RESTful,例如AWS和阿裡雲RPC風格反而占了大多數,Google和Azure則RESTful居多。

Restful API的優勢是HTTP具備更好的易用性,讓異構系統更容易內建,且開發執行效率比較高,面向資源要求也比較高。而RPC API可以使用更廣泛的架構和方案,技術層面更底層也更為靈活,設計起來相對簡單,掌握起來有一定門檻,架構上更加複雜。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

RESTful與RPC模式對比

不同的團隊根據實際情況和業務形态可能選擇不同的方案,那雲服務作為一個整體應該強制統一好還是随意選擇好?如果強制統一風格,有些适合RESTful風格的服務非要使用RPC的話,看起來就會比較醜陋,如果隻是一個過程化的服務調用,往RESTful資源化設計方向去靠會比較困難。但如果不強制使用統一風格,會造成針對API的體系化支援會更加複雜,例如為相容兩種風格SDK的自動化支援需要兩套代碼。

通常RESTful風格對API設計者的要求是比較高的,主要的難點在于面向資源設計要求開發者事先做好規劃,将後端資料模型與API服務模型相比對。是以RESTful API的開發者應該是熟知系統整體實體關系模型的,很難想象一個不懂背景業務的新手能設計出合理的API來。那麼是不是RPC風格API就不需要面向資源設計了呢?從實踐中來看,并不是!RPC風格的API也需要資源模型來支援,在下一節中會重點分析。

是以,對于雲服務商來說,選擇API風格時要考慮幾個問題:

  • 選擇支援哪種風格,才能更好地展現業務特性,讓客戶操作起來更加友善;
  • 設計API時能否面向資源設計,相應的工程人員是否具備做這種設計的能力;
  • 針對這種風格工具鍊的支援是否到位,投入産出比如何;
  • 業界流行的趨勢如何,是否需要考慮與其他系統體系的互操作。

標明了具體設計模式後,就要努力做到統一,避免多種模式混雜帶來管理成本的上升。如果确實有必要兩種方式都支援(例如阿裡雲就同時支援RPC和ROA),就需要在技術上做好充分的準備。

挑戰2:面向資源設計API

使用者使用API來通路雲服務,本質上是想通過對某種雲資源執行特定的操作來完成一個業務動作。Restful API需要面向資源設計衆所周知,那為什麼RPC接口在雲服務場景下也需要有資源模型呢?

RPC形式的API組織形态是領域和行為(對象和方法),随着時間的推移,API越來越多最終形成一個龐大的集合。以阿裡雲為例,對外開放的OpenAPI數量已經達到10000多個,涵蓋了接近200個不同的産品。因為開發者必須單獨學習每個API,耗時又容易出錯,如果沒有一個脈絡的了解起來比較困難。如果有一套标準的資源模型,API就可以按照資源模型的次元分類組織,使用者使用起來也會有迹可循,體驗上會更好,否則面對如此多的API一點點學習無疑是個痛苦的過程。

另外,雲服務并非單個服務的簡單排列,它是多個體系的橫向整合,總體對外呈現出有機連接配接。随着雲計算的發展,企業客戶對對雲服務的要求不斷提高。最典型的就是當企業客戶大規模開始上雲後,對虛拟化的雲産品提出了各種管理需求,例如鑒權、編排、彈性伸縮等。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

企業客戶對雲服務的管理需求

以最常用的鑒權功能為例,客戶建立了一組雲伺服器來跑業務,運維人員需要有重新開機伺服器的權限,其他角色人員則不需要此類權限,針對RestartServer這麼一個API就需要進行權限控制了。權限在雲平台中一般是中心式管理的,單獨的雲産品不需要分别管理。如果統一處理鑒權,就需要知道目前API正在操作什麼資源,與此相關的資源有哪些(例如與伺服器有關的資源包括磁盤、網卡、網絡等關聯資源),然後針對所有相關資源逐一鑒權才能确認API操作是否可行。

上面提到的資源有兩個關鍵點,一是要有統一的資源模型,便于雲産品對特定的API進行鑒權,二是要明确資源關系,當出現資源依賴的時候,需要關聯鑒權。在Google的API Guide中就明确提到需要資源關系,可以看出資源關系不僅僅是用來做API設計模組化的,它對于平台功能的實作也有至關重要的作用。不了解資源關系,有可能把多個資源封裝到一個API中,使用和變更都很痛苦,即便後期發現了問題再補救拆開,由于很多使用者已經在使用了,要付出的開發成本和溝通成本也是極大的,甚至成為不可能。是以清晰的資源模型有利于梳理清楚API體系。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

定義清晰的實體關系圖有助于設計出更為完整的API

而且,明确的資源模型對于建構雲上運維管理基礎設施至關重要,例如可以通過對資源打Tag來對資源進行分類管理(參考阿裡雲資源Tag),分組授權(參考阿裡雲資源組),資源審計(參考阿裡雲CloudConfig),類似開源軟體Terraform這樣的編排工具,由于有資源模型會更容易接入和使用。

是以,統一的資源模型對雲服務的幫助是巨大的:

  • 它可以使API具有更清晰的結構,幫助使用者了解;
  • 它可以幫助對比API與背景實體關系模型,更容易提供更完整的API服務;
  • 它可以使産品協作更加順暢,對資源的操作也更加規範化;
  • 它可以使雲服務底層平台實作起來更統一、更友善;
  • 它可以使圍繞API的生态內建起來更加簡單、高效。

既然有這麼多好處,那麼衆多的雲産品在實際設計API的時候能否堅持以資源為中心,充分考慮到上下遊的需求就變成一個很大的挑戰了。

挑戰3:API設計風格

确定了設計模式和資源模型後,是時候進入到API設計細節了。諸如API名稱、參數名、屬性名稱、資料格式、錯誤碼之類的資訊,看起來根本不是問題。單個産品問題還不大,隻要保證内部風格一緻即可,如果考慮到雲服務多産品對外的整體體驗,就有必要考慮以下問題:

  • 在API命名的時候,遵循什麼樣的範式來確定大體風格相似?動詞、名詞、介詞如何組合才能保持API風格看起來比較統一,降低了解成本?
  • 對于類似的操作,有沒有使用規範?有哪些公共的标準詞彙使得同類型的操作可以比較容易了解,避免使用晦澀奇怪的詞彙(例如讀操作,Read/Query/Describe/List/Get中都在什麼場合使用什麼動詞)?
  • 被廣泛使用的參數如何盡可能保持一緻,避免不同産品的表達混亂的情況(例如分頁參數用PageNumber還是PageNum)?
  • 對于常用的場景,例如幂等、分頁、異步API的設計有沒有統一的規範,避免使用體驗不一緻?
  • 錯誤碼應該怎麼設計?公共錯誤碼怎麼統一,業務錯誤碼怎麼表達?

上述問題都是實際研發過程中要注意的,要全部羅列的話遠不止這些。API的用詞描述是雲服務展現給外部使用者的第一印象,絕非随意寫就。對人員有一定規模,内部有多條産品線的組織來說,如何協調組織的各個部分對外具有統一的體驗是個很大挑戰。

回顧下HTTP協定,最廣為認知的是對HTTP Mehod的約定,使用9個單詞就完成了對基本動作的規範,為開發者提供了清晰的思維模型:

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

Http Method 類型

https://tools.ietf.org/html/rfc7231

同樣,在HTTP Header裡面也對浏覽器資訊、語言、網絡連接配接屬性等做了詳細的規定,這樣開發者在使用HTTP服務的時候都有一個大緻的約定,在關鍵資訊上面不會有偏差,保障了異構系統的接口一緻性。

是以雲服務在管理API時應該考慮一些具體的規範,對命名規則、标準詞彙、最佳實踐模式、錯誤碼等資訊都有明确的規定,同時用系統化、平台化的手段來管理API,確定不走偏。設計風格不是雲服務API設計中緻命的問題,但是它關乎雲服務外表形象,不可不察。

挑戰4:服務端容錯處理

API是後端服務的外部表達,是服務就有可能出現問題,無論這個問題是可預期的還是不可預期的。如果隻考慮功能本身功能特性,而忽視對異常情況的設計,當問題出現的時候業務本身可能無法感覺造成服務異常,更重要的是站在客戶角度去看,不能有效擷取錯誤原因是非常痛苦的,很多時候隻能束手無策,降低雲服務提供商的整體口碑,甚至損害營收。

假設有個建立資源的API,每調用一次都會建立新的資源,考慮以下情況:

  • 同樣的請求多次送出,是否會重複建立資源?
  • 請求處理時間過長,用戶端是長時間等待,還是先異步傳回一個任務ID?
  • 如果需要等待,Timeout最大值是多少?
  • 如果Timeout最大值達到,用戶端的政策是重試還是放棄
  • 如果最終處理還是失敗了,具體是哪個環節的問題?如何給出準确的錯誤資訊?
  • 如果異步方式,異步處理完成後是主動查詢還是另有通知?
  • 第三方工具和內建商到哪裡去擷取這些資訊?能不能有标準化的處理?

實踐中,如果不做好問題a的處理,可能會造成系統異常情況下大批資源被重複建立,有可能造成使用者或雲服務商資損;問題b-e沒有處理好,可能會讓使用者陷入盲目等待或者盲目重試,使用體驗和效率極差;而f-g關系到自動化處理工具如何做到效率最大化,也關系到被內建的效率。

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

一個異步重試的狀态機

當出現異常的時候,API一般是要靠錯誤碼來告知使用者有什麼問題。HTTP協定本身對錯誤碼做出了詳盡的規定,Restful的API要盡可能地符合标準。除此之外,雲服務有必要在此基礎上進一步提供業務錯誤碼和錯誤資訊,來描述錯誤具體的細節。

目前雲服務的錯誤碼很多,看起來非常專業,但問題主要集中在以下幾個方面:

1.錯誤類型過多:錯誤碼越多用戶端處理起來越友善嗎?看一下HTTP的錯誤碼,隻有5大類加幾十個子類的錯誤碼就涵蓋了所有場景,而通常大家耳熟能詳的無非是200、400、404、500、502等屈指可數的狀态碼。有的人考慮錯誤碼越多,用戶端可以switch/case一下針對每個錯誤碼做不同的操作,這個就見仁見智了,一般的程式員可能不會寫那麼多的分支流程,必要性也不大。

2.錯誤資訊表達不夠充分:相比于提供大量的錯誤碼,錯誤資訊的明确表達更為重要。如果錯誤資訊不夠詳細,作為使用者不了解細節無法掌控的雲服務,幾乎是無法明确發生了什麼,要麼提工單,要麼隻能被動等待,客戶體驗很差。

3.業務錯誤碼與HTTP錯誤碼含義不比對:例如參數錯誤應該傳回4xx系列Code,傳回5xx系列就不夠專業。即便是RPC風格的API,也要大緻符合HTTP規則,否則可能會給一些依賴HTTP Code的系統造成誤導。網上有種思路覺得無論背景響應如何,HTTP Code統統傳回200,在Body裡面的錯誤資訊展現異常資訊,這種不利于對接口的監控,因為監控系統很難通過識别消息體來鑒别功能是否正常響應。

4.相同錯誤不同雲産品表達不一緻:這會給用戶端開發造成困擾,增加開發工作量,不利于自動化內建,使用者體驗比較差。

5.錯誤碼應該是可枚舉集合:一個API能夠産生的錯誤碼類型應該是可預期的,即便是業務更新,也應該給客戶提供明确的錯誤碼清單,不能随心所欲。因為使用者端需要明确知道可能會發生什麼,而不是随時可能出現不可預知的錯誤類型。如果錯誤類型不确定,就意味着針對錯誤碼分支處理基本是無效的。

要做好服務端容錯上述問題,需要從雲服務整體層面加強API的容錯設計,做好錯誤碼規範,加強對錯誤資訊的管理,來提升使用者體驗。

挑戰5:版本管理

API都是不斷疊代的,通常都需要版本管理。雲服務API的版本管理尤其重要,主要是以下原因:

  • 雲服務API直接面向使用者,由于調用量大,變更影響的使用者範圍也更廣,版本變更要非常謹慎;
  • 雲服務有多種形态,主要是公有雲、私有雲、細分的行業雲等,不同的雲對同樣功能API的要求可能不一樣,API更加多樣化。既要保障不同版本功能正常,又要能快速部署維護不同版本,挑戰很大;
  • 不相容變更的推廣極其困難,很難讓使用者在短時間内快速更新,維護多版本API成本很高;
  • 必須變更的情況,要確定調用方能夠及時感覺并且平滑切換的技術難度很大。

針對API各種場景的管理,需要一套成熟的API管理平台,照顧到各種場景的需求,也是一項不小的挑戰。

挑戰6:API該如何開放

API如何開放看起來是奇怪的問題,難道API做出來不就是開放給别人用的嗎?做好就開放就開放啊?但在雲服務場景下,情況會更複雜一點!

産品技術都是在不斷疊代的,功能始終在增加,新的API層出不窮。從客戶視角來看,他們對已開發完畢的API是否開放的需求是什麼?假設一個雲産品有100個功能特性,20個隻能保留在内部,官網上總共提供了80個特性,而公開API隻開放了50個,這是使用者期望的狀态嗎?理想狀态應該是什麼?

圍繞雲服務有一個龐大的生态,除了普通的開發者,還有許多第三方服務商、企業客戶、開源工具。當我們考慮所有這些生态成員的需求時會發現:雲服務自身擁有的功能集合與客戶能使用的功能集合之間的差異比較能展現産品的開放程度。這裡的差異強調的是雲服務已經擁有的,不包括雲服務自身沒有的服務。客戶能使用的功能與雲服務能提供的功能之間的差距越大,說明雲産品的開放程度越低,因為很多功能都作為保留節目被雪藏了,導緻客戶和第三方服務商無法享受與雲廠商接近的服務,最終生态無法拓展。理想狀況是,雲服務商自身能通過API使用的功能,客戶都能通過OpenAPI使用,内外看到的是一緻的。

但具體到某個API應不應該開放,實踐中會做如下考慮:

  • API剛剛上線尚未打磨充分,貿然開放可能會留下隐患,再想調整為時已晚,是以選擇先不開放。
  • API本身并非原子化,封裝了若幹業務場景,主要目的是優化性能或者服務特定的客戶,并不需要開放給所有使用者;而且當業務場景發生變化的時候,調整起來也比較困難,不适合開放出去。
  • 某些API不适合開放給全部使用者,隻能部分開放,例如特定行業專業的API。
  • API僅供特定場景或私有場景使用,需要外部能夠通路,但是不能開放給使用者。

針對這些問題,需要在API的管理機制上面下功夫,能夠區分不同的場景,并做好中繼資料的管理。針對API是否開放要有明确的規範和度量機制,確定該開放的API都可以開放,確定内外客戶看到的功能集合基本一緻,才有利于雲服務更好地被內建,在客戶的業務中發揮更大的作用。

挑戰7:API體系如何打通

在雲服務場景中,API并非孤立存在:

首先,API釋出以後,使用者要想順利地使用API,配套設施必不可少,SDK、文檔、工具鍊的內建都需要考慮到,這裡的重點是如何保障準确性、及時性和一緻性。開發工程師一般都不太喜歡寫文檔,專業寫文檔的又可能不太懂技術,再考慮到國際化的問題,就十分有挑戰了。SDK方面,一個API要有多種語言的實作,每種語言還要保障其專業性、可用性,非常考驗對開發人員程式設計語言掌握的深度和對API的了解,業界經常采用的自動化生成SDK的方式也會考驗對多語言的相容能力。工具鍊比如阿裡雲的 API Explorer、CloudShell等産品也需要及時與API的最新狀态保持同步。

其次,雲服務由于産品線衆多,如何讓使用者能夠快速學習使用API和相關工具,需要在教程、案例、運作時環境等諸多方面加強建設。圍繞雲服務,已經發展出許多上層生态工具,例如terraform/ansible/spinnaker等開源軟體,它們能夠幫助雲服務更好地使用起來,必須對它們提供支援,如何能夠快速覆寫也對平台開發能力是個考驗。

另外,API本身的品質保障也是非常重要的。一般都要考慮性能、穩定性、安全等方面的保障體系,通過壓測、監控、部署防護軟體等方式來確定API在服務的時候不會掉鍊子。傳統的套路在解決系統問題時非常有效,但具體到業務問題的時候就無能為力了。例如,一個建立伺服器的API一般來說都是要求幂等的,怎麼檢測該API實際上有沒有做到幂等呢?推而廣之,其他業務流程的正确性又如何保障呢?等API開放了發現問題再修複就為時已晚,顯然應該在上線前通過測試來發現這類問題。但是随着業務的發展,如何能保障這類問題可以有統一的解決方案,能夠長期跟進及時發現風險避免損失呢?

雲服務OpenAPI的7大挑戰,架構師如何應對?為什麼要有API規範挑戰1:選擇API設計模式挑戰2:面向資源設計API挑戰3:API設計風格挑戰4:服務端容錯處理挑戰5:版本管理挑戰6:API該如何開放挑戰7:API體系如何打通

阿裡雲API體系簡易圖

所謂量變引起質變,上述問題針對單個API的時候都好解決,但是當API規模達到成千上萬的時候,就必須通過平台化、系統化的手段來解決了。例如,API服務可靠性SLA名額如果要達到4個9,需要制定明确的标準,并且有手段監控到所有API的運作結果,通過分析成功率來判斷其是否達到預期水準,這對雲服務本身的底層系統建設提出了較高的要求。

是以,以API為中心完善相關體系,保障使用者體驗的一緻性、及時性、穩定性、易用性是非常有挑戰的。

參考文獻:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages https://tools.ietf.org/html/rfc7231#section-4 https://www.cnblogs.com/sparkdev/p/10052310.html https://www.terraform.io/docs/index.html http://www.grabsun.com/article/2015/1135807.html

原文釋出時間為:2019-10-15

作者:虛明

本文來自雲栖社群合作夥伴“

阿裡技術

”,了解相關資訊可以關注“

”。