今年,個人任務是爲公司的私有云平臺( PaaS )開發對應的雲服務平臺(咱們稱之爲插件平臺),這個雲服務平臺的主要任務,是爲雲平臺接入一些服務,服務包括但不限於mysql、redis、cdn等存儲服務,天氣預報等http服務。這個系列文章,但願總結本人在開發這個平臺時的得與失。
下面將雲服務平臺簡稱爲平臺(插件平臺),所接入的服務,簡稱爲第三方服務(插件)html
統一接入方案,是指能夠幫助插件平臺更快接入第三方服務的一種統一方案mysql
首先要回答的第一個問題,是爲何須要插件平臺:web
雲平臺,是一個強大的開發平臺,幫助開發人員完成從機器申請,項目部署,維護(動態擴容……)等一系列操做,像阿里雲、騰訊雲,都是國內這方面作的比較大的平臺。一個完整的雲平臺,必然會接入一些第三方服務。簡單的作法,固然是雲平臺本身完成這個事情。但隨着平臺及人員規模的擴大,一個很合理的分工,是將接入、管理、維護第三方服務的功能,做爲一個獨立的模塊、平臺。這樣符合軟件開發的解耦原則,具體來說,會有如下收益:redis
當雲平臺要升級改造時,不會直接影響到第三方服務。過往的邏輯鏈路,是雲平臺綁定了 N 個第三方服務,而有了插件平臺,這個鏈路變成:雲平臺-> 插件平臺 -> N個第三方服務。過往的狀況是,雲平臺的一些變更,N個第三方服務可能要跟着修改。而如今,只須要由插件平臺統一作變動,而插件平臺到N個第三方服務這條鏈路,能夠保持以前約定的規則不變。另外,雲平臺的一些部署、變動,也能儘可能少地影響到插件服務。sql
插件平臺更專一於插件這個事情,能夠把插件接入、維護這件事情作得更加極致。json
一個插件平臺,能夠對接多個雲平臺 。做爲一箇中間站,插件平臺能夠按照它和每一個雲平臺的約定進行對接,而後再按照插件平臺本身的標準流程,和多個第三方服務進行對接。這樣,每一個雲平臺上,等於都能接入插件平臺提供的第三方服務。安全
能與開源社區結合,打造閉環「廣大開發人員開源組件->孵化成熟->成爲雲平臺第三方服務」,從而提供更多豐富的插件。這是咱們的實踐結果。插件平臺不只爲雲平臺提供第三方服務,同時,咱們還開發了這麼一個網站,每一個開發人員,能夠到這個網站開源本身寫的組件,若是以爲合適,還能夠將這個組件轉成雲平臺適用的第三方服務。markdown
其次,解答統一接入方案的重要性和必要性:說究竟是爲了兩個字,"效率"。沒有統一接入方案時,每來一個新的第三方服務,雲平臺開發人員就須要和第三方服務開發人員討論肯定接口,而後一方(第三方服務)寫接口,一方(平臺)寫調用邏輯,最後進行聯調,很是麻煩。有沒辦法改善呢?固然是有,就是提供一個統一的接入方案,不論是什麼第三方服務,都按照這套規範。平臺的邏輯是通用的,要接入新的第三方服務時,無需開發。第三方服務要按照規範開發幾個接口,再經過頁面配置信息,而後就能接入了。從以前的兩方聯調模式,變成單邊適配。app
首先作第一層抽象,以一個MySql服務爲例,用戶可能須要:建立、刪除、變動、查看(基本參數)一個MySql實例。MySql服務在插件平臺正式上線前,平臺須要知道,如何調用MySql服務的哪些接口以作增刪改差服務資源。所以,統一接入,其實就是解決平臺和第三方服務如何對接這四個接口的問題。
編輯器
調用第三方服務這幾個接口時,如何斷定操做是成功的(特別是建立、刪除操做)
建立一個第三方服務實例,不一樣的用戶,須要建立的實例類型,多是不同的。如何統一?例如,有些項目須要建立帶從庫的 MySql ,有些項目不用。
平臺發送請求時,要帶上哪些參數。不一樣服務,所需參數不同,怎麼在不改平臺帶代碼的狀況下,讓平臺根據服務的不一樣,帶上不一樣的參數。
操做成功及失敗時,分別要返回哪些信息給用戶。如何從第三方服務的接口響應內容中,提取對應的信息
如何讓第三方服務開發者能夠本身調試協議,而無需平臺開發介入
在第三方服務正式上線時,平臺管理員如何快速檢查接口是否符合約定
既然稱之爲統一方案,那麼一定就是要作這幾件事情:制訂一套行之有效的標準流程,定義簡潔清晰的接口規範,提供相關的接入工具。
最終的流程以下
開發者按照約定,開發服務的增刪改查接口
在雲服務平臺填寫服務信息,使用測試工具測試ok後,提交管理員審覈
管理員審覈並上線
這是很常見的一個接入流程。下面咱們具體看看,咱們是如何更簡潔解決上面提到的問題。
第三方服務在收到請求時,固然須要斷定請求來源是否合法,是否來自插件平臺。咱們提供了兩種鑑權方式,供第三方服務開發者選擇:
keystone
插件平臺、公司的私有云平臺,鑑權都基於 openstack 自身的 keystone 模塊,該模塊爲服務間交互的鑑權,提供了一種統一方案。所以,和平臺交互的第三方服務,也能夠採用該方式。
這樣有兩個好處:
從雲平臺、插件平臺、第三方服務,自上而下,鑑權都是統1、標準、可信任
不用本身造輪子
password
平臺和服務之間約定一個密碼,平臺發起請求時,會在 Header 中帶上該密碼,服務在收到請求時,判斷該密碼是否和約定一致
這兩個方式,前者略重,但安全可靠,後者略輕,卻快速簡單。 keystone 是 openstack 的標準方式,它的好處自沒必要說,而 password 這個方式,是考慮到咱們是個私有云,能夠減低安全要求,同時更要儘可能快速簡單地接入第三方服務。
和下面要展開的「請求參數格式"同樣,這裏的關鍵,是如何抽離區分,平臺的統一參數及不一樣服務之間的差別參數。什麼意思呢?哪些是統一的參數,哪些是差別參數。例如,不論是何種第三方服務,建立一個資源後,都須要返回操做的明確結果,資源的id。而其餘的返回參數,則存在差別,例如一個 mysql 服務,還須要告知,資源的 url ,端口號,用戶名,密碼等,而圖片服務,則可能提供一個存儲路徑 url 便可。
咱們是這樣作的:請求、響應設計,遵循 RESTful 設計。RESTful 的特色:經過 HTTP 狀態碼能知道操做結果,經過 HTTP 方法能知道操做類型(增刪改查),經過 Url 能知道操做的資源對象。這些特色,恰好和服務接入的標準不謀而合。所以,咱們約定:
請求響應碼,操做成功返回200,不然返回4xx,5xx。平臺只經過狀態碼來判斷操做成功與否。
標準的返回內容(示例)以下:
{ "id": "68788943-d109-416b-983d-e3df70a9463b", "config_vars": { "port": "3306", "host": "d9888.mysql.oa.com", "slave_host": "fd9888.slave.mysql.oa.com", "default_db": "db_name", "user": "a742e2fe34d6", "password": "12345678" }, "message": "success!!!" }
上面是 MySql 服務的返回例子。對於全部服務,咱們都約定,返回格式統一使用 json,json第一級要包含 id ,message ,config_vars 這三個屬性。其中,id 爲資源 id,後續對該資源的刪除,變動,都經過該id進行。message 爲附帶的消息,特別是操做失敗時,方便告知用戶失敗的緣由。config_vars 中,會包含跟服務相關的差別參數,不一樣服務的參數,是不同的。在最終的信息配置頁面,提供了以下的配置功能
在該頁面中,開發者能夠配置 config_vars 中的參數。而平臺在收到實際請求時,也會去驗證 config_vars 中是否包含這些參數,以確保請求有效性。
上面咱們提到,同一個第三方服務,會有不一樣的類型,並對應不一樣的請求參數。仍是以MySql爲例,假設咱們將參數的配置直接扔給用戶,例如用戶須要一個 MySql,頁面提供好幾個填寫項:是否帶從庫、buffer 內容要多大,是否爲 SSD 硬盤等等,用戶本身填寫,而後才能建立一個 MySql。這樣是否會讓用戶以爲很懵呢?用戶能懂怎麼填嗎?用戶是否真的須要這些選項呢?
爲了讓用戶選擇更加簡易,咱們加入了套餐的概念。由第三方服務開發者定義幾個套餐,例如,高級套餐對應配置比較高的服務,中級、低級套餐則配置低些。用戶在選擇時,能夠先了解每一個套餐對應哪些參數,而後再肯定用哪一個套餐。當用戶選擇套餐(無需輸入參數值)後,平臺在後臺組裝對應套餐的實際參數,並調用第三方服務的接口。
做用 | Url | HTTP 方法 |
---|---|---|
添加插件(服務)到用戶項目 | {url} | POST |
從用戶項目中刪除指定插件資源 | {url}/{id} | DELETE |
修改指定的用戶插件資源參數 | {url}/{id} | PUT |
查看指定插件資源參數 | {url}/{id} | GET |
無論服務如何變化,總有一些信息是不變的,都要帶上的。對於這些通用的信息,咱們會將其放在Header中。請求參數( request param )中不包含這些信息,更專一於跟服務相關的參數。
這些通用信息包括:
鑑權串。如上文提到的 keystone 串,password 串等
用戶ID。哪一個用戶在控制檯要求插件平臺發起這次請求
項目ID。例如,告知 MySql 服務,是哪一個項目要求建立一個 MySql 資源。
來源。控制檯(前臺)頁面,是哪一個系統。用戶能夠在私有云平臺上建立一個第三方服務資源,也能夠在插件平臺界面上建立。這是個輔助信息,沒前三個那麼重要。
一份請求內容示例:
{ "plan": "xxxx", "config": { "DISK": "SSD", "plan": "BASIC02", "MEMORY": "2", "REPLICATION": "0" } }
在調用POST(建立)請求時,會帶上如上參數。和響應格式的約定同樣,也是採用 json,第一級是約定的參數名plan,config。全部自定義參數會放在config中。在平臺管理頁面,提供了對應的配置能力。
經過下圖所示,配置請求的參數名
經過下圖所示,配置套餐及各個參數對應的參數值。支持配置接口參數值及在頁面顯示給用戶的文本值。
用戶在使用第三方服務前,能夠經過頁面瞭解該服務。咱們定義了一些關鍵信息,要求服務開發者填寫:
插件名稱。包含中文、英文名字。英文名字用於程序、接口的交互
類別
摘要。幾十個字歸納說明
插件特色。對摘要的簡單補充
圖標。能夠美化頁面,一開始擔憂開發者抱怨圖標很差找。後來發現偏偏相反,不少很讚的圖標。
套餐。
文檔。詳細的說明、使用文檔。文檔約定使用markdown,以帶來更統一的文檔閱讀體驗。
咱們提供了一個頁面,幫助第三方服務開發者管理本身的插件(服務),包括瞭如下模塊:
信息管理
基礎信息編輯
服務配置,包括接口url,請求參數,響應參數,套餐配置
一個基於markdown的說明文檔編輯器
接口測試工具
貢獻率圖表。經過雲平臺總項目數、插件數、使用量等,按公式計算貢獻率,以反映該插件的價值
用戶列表。使用該插件的項目列表。
第三方服務接入的一個痛點,就是兩方要一塊兒調試,這會浪費雙方不少時間。所以,咱們設計了一個簡單易用的web測試工具。
先曬一下界面
這個工具能夠幫助開發者、平臺管理員,快速測試第三方服務接口。打開該工具,能夠看到:
請求url
請求body
指望返回
實際返回
測試結論
當用戶點擊右上角的「測試"按鈕時,將按照圖中所示的url及請求body進行測試,測試完畢後,將顯示實際返回,並和指望返回作對比,得出測試結論。
實踐證實,該工具備效提升了聯調的效率。第三方服務經過該工具能夠本身檢查接口是否符合規範,而無需平臺管理員介入。
首先,開篇提出現狀,咱們須要爲雲平臺提供一個平臺,專門用於管理、接入第三方服務。當平臺和第三方服務聯調相應接口後,服務才能正式上線,普通用戶才能經過平臺來建立對應的第三方服務資源。爲了更快地測試、接入第三方服務,平臺須要定義一套對全部第三方服務都行之有效的規範。
而後,展開解決思路以下:
咱們先是梳理了不一樣服務在接入時,接口、操做類型、請求參數、響應格式的相同點及不一樣點,發現了RESTful設計理念和咱們接口設計至關契合,所以引入了RESTful來定義接口規範:同個服務的不一樣操做類型(增刪改查)對應同個Url,經過HTTP 方法來表達具體的操做類型。
請求參數、響應格式設計,努力求同存異,經過HTTP狀態碼來表達操做的結果,簡單明瞭;而內容則約定爲json格式——當前最流行的HTTP內容格式;在請求及響應內容的第一級,都是約定的參數名,將有差別,自定義的內容都指定放於某個指定參數中的第二級中,從而在內容格式上取得統一。
開發者經過頁面填寫自定義參數、各類套餐。這樣平臺就不用爲了新接入一個第三方服務寫代碼,直接讀配置,就能組裝對應的請求格式。當用戶選擇套餐時,平臺將把套餐對應的參數值發給第三方服務。
最後,爲了方便聯調,提升效率,還提供了一個強大的在線測試工具。固然,若是沒有上述的規範,也沒有辦法造成標準的測試流程,沒辦法打造這款測試工具。