Re:從 0 開始的微服務架構--(三)微服務架構 API 的開發與治理--轉

原文來自:聊聊架構公衆號git

前面的文章中有說到微服務的通訊方式,Martin Folwer 先生在他對微服務的定義中也提到「每一個服務運行在其獨立的進程中,服務與服務間採用 輕量級的通訊機制 互相協做(一般是基於 HTTP 協議的 RESTful API)」。程序員

那麼,在各個微服務之間具體怎麼進行輕量級的通訊呢?這篇文章就來聊聊微服務 API 開發及治理的幾個方面。github

首先須要解釋一下,標題中的「內網環境中 的 API」指的是提供給內網裏的其它微服務調用的 API。與其相對應的是「開放給互聯網 用戶調用的 API」,它們的開發方法大致相同,但治理方法卻不太同樣。api

例如開放給互聯網用戶調用的 API 須要在 API 網關上加上受權、鑑權、限流、限併發、統計、計費等等功能。架構

本篇文章分享的是內網環境中的 API 開發及治理。併發

API 開發框架

API 開發,首先考慮的就是該用什麼樣的協議,是 HTTP API 仍是 RPC?微服務

咱們先來介紹一下這兩種 API 類型:工具

 HTTP API性能

HTTP API 指的是簡單的基於 HTTP 協議的 API,具體的例子就是 Spring MVC 的 Controller,例如 

http://127.0.0.1/helloworld/myapi.do」

 RPC

RPC 就是 Remote Procedure Call,中文名遠程過程調用,在 API 調用的場景下,大多指的是基於 Socket 通訊方法的遠程調用(固然,咱們也可使用 HTTP 協議來實現 RPC 調用,例如 gRPC)。Json-RPC 和 Xml-RPC 指的是使用 Json 或 Xml 做爲文本格式的方式傳輸命令和數據。

那麼回到剛纔那個問題,到底要使用 HTTP API 仍是 RPC 呢?咱們之所要對比 HTTP API 和 RPC,主要是由於你們都知道 HTTP 簡單,而基於 Socket 的 RPC 性能更好

這個問題咱們糾結了好久,直到後來,想明白了下面兩件事,最終決定在絕大部分場景中使用 HTTP API。

HTTP API 的性能足以支撐大多數項目

一般來說(根據資料),算上序列化的時間,RPC 協議的吞吐量是 HTTP 性能 兩倍(沒有親測),例如 Protobuf、Thrift、Kyro、Dubbo 等等。

這裏面,又以 Thrift 的性能最高。具體的性能測試報告能夠參考《RPC 框架性能基本比較測試》。

咱們團隊在結合自身技術棧、成本、穩定性、易用性、可維護性、業務場景等等因素綜合考慮後,以爲咱們面臨的大多數場景中,HTTP 和 RPC 的性能差異並非主要問題

再加上下圖所示的 HTTP 性能測試結果做爲佐證,咱們徹底能夠採用 HTTP API 的方式來進行微服務 API 開發。

再者,當業務發展到必定的程度,若是某些業務功能的性能壓力變大時,咱們仍是可使用 RPC 小範圍地進行改造。這也是符合敏捷思想的一個決定。

下圖是對 helloworld 頁面進行 10000 次連續請求的測試結果,總耗時 1.504 秒,平均每一個請求耗時 0.15 毫秒。

測試環境:原生 Tomcat7(沒有任何優化)運行在本地虛擬機上

下面是對 helloworld 頁面以 100 併發數進行 10 萬次請求的測試結果,平均每一個請求耗時 11.9 毫秒。

測試環境:原生 Tomcat7(沒有任何優化)運行在本地虛擬機上

因此,按照上面的測試結果,HTTP API 方式的性能徹底足以支撐絕大多數的微服務 API 開發。讓咱們把 RPC 方式留給那些可能出現雙十一業務量的大型互聯網公司去玩

RESTful API 適用於開放 API 的場景

這是另外一個折磨人的問題。相對於 HTTP API,RESTful API 在 HTTP API 的基礎上增長了一些很是抽象晦澀的概念,例如資源(Resource)、表述(REpresentation)、狀態轉移(State Transfer)、統一接口(Uniform Interface)……。

在經歷了一次又一次的折磨,例如「login/logout 是什麼 RESTful 方法?」、「批量刪除該怎麼實現?」、「RESTful 的 resource 究竟該怎麼定義?」以後,愈來愈感受這是一個形而上學的問題,太過於抽像。

咱們不應盲從於時髦的技術,須要加上技術人的基於自身狀況的理性思考。因此,RESTful 雖好,但不是咱們團隊的菜。

再者,即便團隊中有些人能夠理解並正確地實踐,也很難或者說不可能讓整個團隊來正確地實踐這樣一種方法。

因此,咱們在一番掙扎後,選擇了 HTTP API 方式,原來怎麼開發,如今仍是怎麼開發,把主要精力放到了 API 的監控和治理上面。

這裏推薦你們看看知乎上的這篇討論 《WEB 開發中,使用 JSON-RPC 好,仍是 RESTful API 好?》,幾位大神講得都挺好。

[https://www.zhihu.com/question/28570307]

API 治理API 文檔

API 存在的意義在於有人調用它,若是調用方在調用 API 的時候很麻煩,甚至不能正確地調用,那麼團隊內部及團隊之間的溝通成本及配合程度就會大受影響。

咱們是經過文檔來溝通的,項目開始的時候還好,但隨着時間的推移,文檔的更新變得不是那麼及時(這實際上是個自我辯解的說法,事實是大部分狀況下文檔都不更新了),API 變動時,也不容易找出哪些模塊調用了這個 API。

因此,得先解決 文檔不及時更新 的問題。雖然咱們能夠經過流程管理的方式來強制你們更新文檔,但這對於開發人員來講,顯然是不夠科學或人性化的,由於變動一個 API,就要在兩個地方進行修改,一是 API 代碼,二是 API 文檔,程序員的思惟就得在代碼和文檔之間不斷切換,工做效率必然受影響。

咱們就想,能不能只須要在同一個地方修改,若是能作到,API 文檔的更新就沒有那麼麻煩了,於人於已都是好事。

通過調研,咱們選擇使用 Swagger 來編寫文檔,按照 Swagger 的規範,在 API 上加一些描述性的 Annotation 就能夠了。

經過以上的 Annotation,將自動生成如下在線 API 文檔。

調用方能夠在 API 文檔界面填入參數並點擊「Try it out!」按鈕嘗試調用這個 API。這樣,在沒有 API 提供方支持的狀況下,便可以自行完成絕大部分的 API 調用,是否是很爽?

調用鏈管理

API 開發出來了,API 文檔也寫好了,接下來就是被調用了。前篇文章講到,經過 Spring Cloud 的 Eureka + Ribbon + Zuul 能夠很方便地調用到這些 API。

那麼,如何來追蹤 API 被誰調用了,調用是否出錯及出錯緣由,調用鏈路裏各個 API 的性能怎麼樣,是否是存在殭屍 API……這些都是關於 API 治理的問題。

實現這個目標,有一個比較取巧的方法,就是在 Ribbon 的客戶端裏作點文章,在調用 API 以前記錄一下開始時間,API 調用返回後,記錄 API 調用耗時、調用狀態,若是有錯則記錄一下錯誤緣由。

若是還想追蹤調用鏈,能夠在請求頭裏加上一個調用鏈 ID,這樣就來把調用關係都串連起來。

下邊是咱們本身研發的調用鏈管理組件(DCTrace)的幾個效果圖:

查看微服務之間的調用關係,調用性能

查看調用失敗緣由

圖形化查看調用關係,太亂 ,下次迭代改進一下 [攤手]

站在技術管理者的角度,能夠從調用鏈裏看出來,哪些模塊之間發生了不正當關係 [噗嗤];哪些模塊之間本該有關係的,事實卻沒有;經過對比 Swagger 和調用鏈的 API 清單,找出殭屍 API……

API 測試

使用微服務架構後,API 是每一個微服務的 惟一能力出口。因爲互聯網行業的快速發展,軟件需求變動變得愈來愈頻繁,迭代升級的速度變得愈來愈快。

對於提供方來講,須要保證變動和迭代的過程當中,不影響以前承諾的功能(包括正確性、穩定性和性能等)。

對於調用方來講,一樣須要確保自身依賴的 API 能正常使用,不能由於其它模塊的錯誤而致使自身業務受到影響(包括正確性、穩定性和性能等)。

畢竟,從組織角度來看,系統出錯就是出錯,無論緣由是自身致使的仍是服務提供方致使的,因此 服務調用方就須要對服務提供方進行管理

這也就是前幾年契約測試(Pact)方法大行其道的緣由。有興趣的朋友能夠去看看這種測試方法。

對於 API 白盒測試,推薦使用基於 Java 的 REST-Assured 測試框架,用起來特別方便。

[https://github.com/rest-assured/rest-assured]

更進一步,基於 HTTP 協議、JSON/XML 報文的規範性,徹底能夠開發一個 API 測試小工具(暫且叫它 小鷹 吧)來替換 REST-Assured。咱們也暫未實踐,只是以爲會頗有用,供你們參考。

基礎步驟是:

  1. 服務提供方開發 API,並正確書寫 Swagger 文檔。

  2. 服務提供方在小鷹的界面上選擇須要測試的 API,並填寫測試參數。(API 清單和參數均可以經過調用 Swagger 的 API 獲取)

  3. 服務調用方根據自已的理解,也將對本身有用的服務方提供的 API 配置到小鷹上。

  4. 小鷹 7*24 小時爲服務提供方和調用方巡視這些 API,並在異常出現時發送警報。

總   結

因此,對於微服務 API 開發,咱們

  • 使用最多見的技術(例如 Spring MVC)進行 API 開發

  • 使用 REST-Assured(以及將來的 小鷹)進行測試

  • 使用 Swagger 來管理 API 文檔

  • 使用自研的 DCTrace 進行調用鏈管理

相關文章
相關標籤/搜索