雲服務OpenAPI的7大挑戰,架構師如何應對?


阿里妹導讀:API 是模塊或者子系統之間交互的接口定義。好的系統架構離不開好的 API 設計,而一個設計不夠完善的 API 則註定會致使系統的後續發展和維護很是困難。比較好的API設計樣板能夠參考 github 和 k8s ,它們都是典型的RESTful接口。雲服務對外開放的窗口就是OpenAPI,今天要討論的話題是「雲服務場景下OpenAPI設計的挑戰」。html

爲何要有API規範

之因此強調「雲服務」的緣由在於,小規模獨立API的設計與大規模批量生產API面臨的問題是不同的。一樣,只專一於自身產品API的可用性與從更高的層次去看雲服務總體API體系的健壯性,要建設的體系也是不同的。git

例如,作一個WEB頁面使用的API,只須要考慮性能、穩定性、鑑權就好,由於頁面與API是一體的,能夠一塊兒發佈和回滾,只要功能正常,即使API設計有缺陷,用戶也能夠接受。而云服務要開放API考慮問題就多了:程序員

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

因此雲服務因爲產品線衆多,須要統一的API規範來保證雲產品間API體驗一致,在底層平臺層面互相兼容,便於上層應用平臺化,同時要兼顧到圍繞公有云服務的第三方生態、開源生態、企業生態。github

在具體規範層面,業界也在不斷嘗試,比較知名的是OpenAPI Specfication和 Google API Design Guide。前者針對RESTful API設計在細節層面給出了很是具體的規定,已經成爲RESTful API設計領域的事實標準,然後者則主要從雲廠商的角度提出許多最佳實踐性質的規範與建議,這些原則不只僅適用於RESTful API,也適合其餘類型API設計。對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等,用於封裝傳輸數據。但涉及到不一樣的產品時,在具體選型時考慮的問題可能就不太同樣了。api


gRPC示意圖
圖片來源:https://www.grpc.io/docs/guides/瀏覽器

雖然RESTful設計風格曝光率很高,但並非全部雲服務商都選擇了徹底遵循RESTful,例如AWS和阿里雲RPC風格反而佔了大多數,Google和Azure則RESTful居多。安全

Restful API的優點是HTTP具有更好的易用性,讓異構系統更容易集成,且開發執行效率比較高,面向資源要求也比較高。而RPC 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一點點學習無疑是個痛苦的過程。

另外,雲服務並不是單個服務的簡單排列,它是多個體系的橫向整合,整體對外呈現出有機鏈接。隨着雲計算的發展,企業客戶對對雲服務的要求不斷提升。最典型的就是當企業客戶大規模開始上雲後,對虛擬化的雲產品提出了各類管理需求,例如鑑權、編排、彈性伸縮等。


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

以最經常使用的鑑權功能爲例,客戶建立了一組雲服務器來跑業務,運維人員須要有重啓服務器的權限,其餘角色人員則不須要此類權限,針對RestartServer這麼一個API就須要進行權限控制了。權限在雲平臺中通常是中心式管理的,單獨的雲產品不須要分別管理。若是統一處理鑑權,就須要知道當前API正在操做什麼資源,與此相關的資源有哪些(例如與服務器有關的資源包括磁盤、網卡、網絡等關聯資源),而後針對全部相關資源逐一鑑權才能確認API操做是否可行。

上面提到的資源有兩個關鍵點,一是要有統一的資源模型,便於雲產品對特定的API進行鑑權,二是要明確資源關係,當出現資源依賴的時候,須要關聯鑑權。在Google的API Guide中就明確提到須要資源關係,能夠看出資源關係不只僅是用來作API設計建模的,它對於平臺功能的實現也有相當重要的做用。不瞭解資源關係,有可能把多個資源封裝到一個API中,使用和變動都很痛苦,即使後期發現了問題再補救拆開,因爲不少用戶已經在使用了,要付出的開發成本和溝通成本也是極大的,甚至成爲不可能。因此清晰的資源模型有利於梳理清楚API體系。


定義清晰的實體關係圖有助於設計出更爲完整的API

並且,明確的資源模型對於構建雲上運維管理基礎設施相當重要,例如能夠經過對資源打Tag來對資源進行分類管理(參考阿里雲資源Tag),分組受權(參考阿里雲資源組),資源審計(參考阿里雲CloudConfig),相似開源軟件Terraform這樣的編排工具,因爲有資源模型會更容易接入和使用。

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

  • 它可使API具備更清晰的結構,幫助用戶理解;
  • 它能夠幫助對比API與後臺實體關係模型,更容易提供更完整的API服務;
  • 它可使產品協做更加順暢,對資源的操做也更加規範化;
  • 它可使雲服務底層平臺實現起來更統1、更方便;
  • 它可使圍繞API的生態集成起來更加簡單、高效。

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

挑戰3:API設計風格

肯定了設計模式和資源模型後,是時候進入到API設計細節了。諸如API名稱、參數名、屬性名稱、數據格式、錯誤碼之類的信息,看起來根本不是問題。單個產品問題還不大,只要保證內部風格一致便可,若是考慮到雲服務多產品對外的總體體驗,就有必要考慮如下問題:

  • 在API命名的時候,遵循什麼樣的範式來確保大致風格類似?動詞、名詞、介詞如何組合才能保持API風格看起來比較統一,下降理解成本?
  • 對於相似的操做,有沒有使用規範?有哪些公共的標準詞彙使得同類型的操做能夠比較容易理解,避免使用晦澀奇怪的詞彙(例如讀操做,Read/Query/Describe/List/Get中都在什麼場合使用什麼動詞)?
  • 被普遍使用的參數如何儘量保持一致,避免不一樣產品的表達混亂的狀況(例如分頁參數用PageNumber仍是PageNum)?
  • 對於經常使用的場景,例如冪等、分頁、異步API的設計有沒有統一的規範,避免使用體驗不一致?
  • 錯誤碼應該怎麼設計?公共錯誤碼怎麼統一,業務錯誤碼怎麼表達?

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

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


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關係到自動化處理工具如何作到效率最大化,也關係到被集成的效率。


一個異步重試的狀態機

當出現異常的時候,API通常是要靠錯誤碼來告知用戶有什麼問題。HTTP協議自己對錯誤碼作出了詳盡的規定,Restful的API要儘量地符合標準。除此以外,雲服務有必要在此基礎上進一步提供業務錯誤碼和錯誤信息,來描述錯誤具體的細節。

當前雲服務的錯誤碼不少,看起來很是專業,但問題主要集中在如下幾個方面:

1.錯誤類型過多:錯誤碼越多客戶端處理起來越方便嗎?看一下HTTP的錯誤碼,只有5大類加幾十個子類的錯誤碼就涵蓋了全部場景,而一般你們耳熟能詳的無非是200、400、40四、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開放了發現問題再修復就爲時已晚,顯然應該在上線前經過測試來發現這類問題。可是隨着業務的發展,如何能保障這類問題能夠有統一的解決方案,可以長期跟進及時發現風險避免損失呢?


阿里雲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.grpc.io/docs/guides/
https://www.terraform.io/docs/index.html
http://www.grabsun.com/article/2015/1135807.html

 

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索