深刻理解微服務架構:銀彈or焦油坑?

深刻理解微服務架構:銀彈or焦油坑?

本文已收錄GitHub,更有互聯網大廠面試真題,面試攻略,高效學習資料等git

微服務是近幾年很是火熱的架構設計理念,大部分人認爲是 Martin Fowler 提出了微服務概念,但事實上微服務概念的歷史要早得多,也不是 Martin Fowler 創造出來的,Martin只是將微服務進行了系統的闡述。不過不可否認 Martin 在推進微服務起到的做用,微服務能火,Martin 功不可沒。github

微服務的定義相信你早已耳熟能詳,參考維基百科,我就來簡單梳理一下微服務的歷史吧面試

  • 2005 年:Dr. Peter Rodgers 在 Web Services Edge 大會上提出了「Micro-Web-Services」的概念。
  • 2011 年:一個軟件架構工做組使用了「microservice」一詞來描述一種架構模式。
  • 2012 年:一樣是這個架構工做組,正式肯定用「microservice」來表明這種架構。
  • 2012 年:ThoughtWorks 的 James Lewis 針對微服務概念在 QCon San Francisco2012 發表了演講。
  • 2014 年:James Lewis 和 Martin Fowler 合寫了關於微服務的一篇學術性的文章,詳細闡述了微服務。

因爲微服務的理念中也包含了「服務」的概念,而 SOA 中也有「服務」的概念,咱們天然而然地會提出疑問:微服務與 SOA 有什麼關係?有什麼區別?爲什麼有了 SOA 還要提微服務?這幾個問題是理解微服務的關鍵,不然若是隻是跟風拿來就用,既不會用,也用很差,用了不但沒有效果,反而還可能有反作用。shell

本文就來深刻理解微服務,究竟是銀彈仍是焦油坑數據庫

微服務與SOA的關係

對於瞭解過 SOA 的人來講,第一次看到微服務這個概念確定會有所疑惑:爲什麼有了 SOA還要提微服務呢?等到簡單看完微服務的介紹後,可能不少人更困惑了:這不就是 SOA嗎?網絡

關於 SOA 和微服務的關係和區別,大概分爲下面幾個典型的觀點。架構

微服務是 SOA 的實現方式app

以下圖所示,這種觀點認爲 SOA 是一種架構理念,而微服務是 SOA 理念的一種具體實現方法。例如,「微服務就是使用 HTTP RESTful 協議來實現 ESB 的 SOA」「使用 SOA 來構建單個系統就是微服務」和「微服務就是更細粒度的 SOA」。運維

深刻理解微服務架構:銀彈or焦油坑?

微服務是去掉 ESB 後的 SOAide

以下圖所示,這種觀點認爲傳統 SOA 架構最廣爲人詬病的就是龐大、複雜、低效的 ESB,所以將 ESB 去掉,改成輕量級的 HTTP 實現,就是微服務。

深刻理解微服務架構:銀彈or焦油坑?

微服務是一種和 SOA 類似但本質上不一樣的架構理念

以下圖所示,這種觀點認爲微服務和 SOA 只是有點相似,但本質上是不一樣的架構設計理念。類似點在於下圖中交叉的地方,就是二者都關注「服務」,都是經過服務的拆分來解決可擴展性問題。本質上不一樣的地方在於幾個核心理念的差別:是否有 ESB、服務的粒度、架構設計的目標等。

深刻理解微服務架構:銀彈or焦油坑?

以上觀點看似都有必定的道理,但都有點差異,到底哪一個纔是準確的呢?單純從概念上是難以分辨的,我來對比一下 SOA 和微服務的一些具體作法,再來看看到底哪種觀點更加符合實際狀況。

1.服務粒度

總體上來講,SOA 的服務粒度要粗一些,而微服務的服務粒度要細一些。例如,對一個大型企業來講,「員工管理系統」就是一個 SOA 架構中的服務;而若是採用微服務架構,則「員工管理系統」會被拆分爲更多的服務,好比「員工信息管理」「員工考勤管理」「員工假期管理」和「員工福利管理」等更多服務。

2.服務通訊

SOA 採用了 ESB 做爲服務間通訊的關鍵組件,負責服務定義、服務路由、消息轉換、消息傳遞,整體上是重量級的實現。微服務推薦使用統一的協議和格式,例如,RESTful 協議、RPC 協議,無須 ESB 這樣的重量級實現。Martin Fowler 將微服務架構的服務通信理念稱爲「Smart endpoints and dumb pipes」,簡單翻譯爲「聰明的終端,愚蠢的管道」。之因此用「愚蠢」二字,其實就是與 ESB 對比的,由於 ESB 太強大了,既知道每一個服務的協議類型(例如,是 RMI 仍是 HTTP),又知道每一個服務的數據類型(例如,是 XML 仍是 JSON),還知道每一個數據的格式(例如,是 2017-01-01 仍是 01/01/2017),而微服務的「dumb pipes」僅僅作消息傳遞,對消息格式和內容一無所知。

3.服務交付

SOA 對服務的交付並無特殊要求,由於 SOA 更多考慮的是兼容已有的系統;微服務的架構理念要求「快速交付」,相應地要求採起自動化測試、持續集成、自動化部署等敏捷開發相關的最佳實踐。若是沒有這些基礎能力支撐,微服務規模一旦變大(例如,超過 20 個微服務),總體就難以達到快速交付的要求,這也是不少企業在實行微服務時踩過的一個明顯的坑,就是系統拆分爲微服務後,部署的成本呈指數上升。

4.應用場景

SOA 更加適合於龐大、複雜、異構的企業級系統,這也是 SOA 誕生的背景。這類系統的典型特徵就是不少系統已經發展多年,採用不一樣的企業級技術,有的是內部開發的,有的是外部購買的,沒法徹底推倒重來或者進行大規模的優化和重構。由於成本和影響太大,只能採用兼容的方式進行處理,而承擔兼容任務的就是 ESB。

微服務更加適合於快速、輕量級、基於 Web 的互聯網系統,這類系統業務變化快,須要快速嘗試、快速交付;同時基本都是基於 Web,雖然開發技術可能差別很大(例如,Java、C++、.NET 等),但對外接口基本都是提供 HTTP RESTful 風格的接口,無須考慮在接口層進行相似 SOA 的 ESB 那樣的處理。

綜合上述分析,我將 SOA 和微服務對好比下:

深刻理解微服務架構:銀彈or焦油坑?

所以,咱們能夠看到,SOA 和微服務本質上是兩種不一樣的架構設計理念,只是在「服務」這個點上有交集而已,所以二者的關係應該是上面第三種觀點。

其實,Martin Fowler 在他的微服務文章中,已經作了很好的提煉:

In short, the microservice architectural style is an approach todeveloping a single application as a suite of small services, eachrunning in its own process and communicating with lightweightmechanisms, often an HTTP resource API. These services are builtaround business capabilities and independently deployable by fullyautomated deployment machinery.

上述英文的三個關鍵詞分別是:small、lightweight、automated,基本上濃縮了微服務的精華,也是微服務與 SOA 的本質區別所在。

經過前面的詳細分析和比較,彷佛微服務本質上就是一種比 SOA 要優秀不少的架構模式,那是否意味着咱們都應該把架構重構爲微服務呢?

其實否則,SOA 和微服務是兩種不一樣理念的架構模式,並不存在孰優孰劣,只是應用場景不一樣而已。咱們介紹 SOA 時候提到其產生歷史背景是由於企業的 IT 服務系統龐大而又複雜,改形成本很高,但業務上又要求其互通,所以纔會提出 SOA 這種解決方案。若是咱們將微服務的架構模式生搬硬套到企業級 IT 服務系統中,這些 IT 服務系統的改形成本可能遠遠超出實施 SOA 的成本。

微服務的陷阱

單純從上面的對比來看,彷佛微服務大大優於 SOA,這也致使了不少團隊在實踐時不加思考地採用微服務——既不考慮團隊的規模,也不考慮業務的發展,也沒有考慮基礎技術的支撐,只是以爲微服務很牛就趕忙來實施,覺得實施了微服務後就什麼問題都解決了,而一旦真正實施後才發現掉到微服務的坑裏面去了。

咱們看一下微服務具體有哪些坑:

1.服務劃分過細,服務間關係複雜

服務劃分過細,單個服務的複雜度確實降低了,但整個系統的複雜度卻上升了,由於微服務將系統內的複雜度轉移爲系統間的複雜度了。

從理論的角度來計算,n 個服務的複雜度是 n×(n-1)/2,總體系統的複雜度是隨着微服務數量的增長呈指數級增長的。下圖形象了說明了總體複雜度:

深刻理解微服務架構:銀彈or焦油坑?

粗粒度劃分服務時,系統被劃分爲 3 個服務,雖然單個服務較大,但服務間的關係很簡單;細粒度劃分服務時,雖然單個服務小了一些,但服務間的關係卻複雜了不少。

2.服務數量太多,團隊效率急劇降低

微服務的「微」字,自己就是一個陷阱,不少團隊看到「微」字後,就想到必須將服務拆分得很細,有的團隊人員規模是 5 ~ 6 我的,然而卻拆分出 30 多個微服務,平均每一個人要維護 5 個以上的微服務。

這樣作給工做效率帶來了明顯的影響,一個簡單的需求開發就須要涉及多個微服務,光是微服務之間的接口就有 6 ~ 7 個,不管是設計、開發、測試、部署,都須要工程師不停地在不一樣的服務間切換。

  • 開發工程師要設計多個接口,打開多個工程,調試時要部署多個程序,提測時打多個包。
  • 測試工程師要部署多個環境,準備多個微服務的數據,測試多個接口。
  • 運維工程師每次上線都要操做多個微服務,而且微服務之間可能還有依賴關係。

3.調用鏈太長,性能降低

因爲微服務之間都是經過 HTTP 或者 RPC 調用的,每次調用必須通過網絡。通常線上的業務接口之間的調用,平均響應時間大約爲 50 毫秒,若是用戶的一塊兒請求須要通過 6 次微服

務調用,則性能消耗就是 300 毫秒,這在不少高性能業務場景下是難以知足需求的。爲了支撐業務請求,可能須要大幅增長硬件,這就致使了硬件成本的大幅上升。

4.調用鏈太長,問題定位困難

系統拆分爲微服務後,一次用戶請求須要多個微服務協同處理,任意微服務的故障都將致使整個業務失敗。然而因爲微服務數量較多,且故障存在擴散現象,快速定位究竟是哪一個微服務故障是一件複雜的事情。下面是一個典型樣例。

深刻理解微服務架構:銀彈or焦油坑?

Service C 的數據庫出現慢查詢,致使 Service C 給 Service B 的響應錯誤,Service B 給Service A 的響應錯誤,Service A 給用戶的響應錯誤。咱們在實際定位時是不會有樣例圖中這麼清晰的,最開始是用戶報錯,這時咱們首先會去查 Service A。致使 Service A 故障的緣由有不少,咱們可能要花半個小時甚至 1 個小時才能發現是 Service B 返回錯誤致使的。因而咱們又去查 Service B,這至關於重複 Service A 故障定位的步驟……如此循環下去,最後可能花費了幾個小時才能定位到是 Service C 的數據庫慢查詢致使了錯誤。

若是多個微服務同時發生不一樣類型的故障,則定位故障更加複雜,以下圖所示。

深刻理解微服務架構:銀彈or焦油坑?

Service C 的數據庫發生慢查詢故障,同時 Service C 到 Service D 的網絡出現故障,此時究竟是哪一個緣由致使了 Service C 返回 Error 給 Service B,須要大量的信息和人力去排查。

5.沒有自動化支撐,沒法快速交付

若是沒有相應的自動化系統進行支撐,都是靠人工去操做,那麼微服務不但達不到快速交付的目的,甚至還不如一個大而全的系統效率高。例如:

  • 沒有自動化測試支撐,每次測試時須要測試大量接口。
  • 沒有自動化部署支撐,每次部署 6 ~ 7 個服務,幾十臺機器,運維人員敲 shell 命令逐臺部署,手都要敲麻。
  • 沒有自動化監控,每次故障定位都須要人工查幾十臺機器幾百個微服務的各類狀態和各類日誌文件。

6.沒有服務治理,微服務數量多了後管理混亂

信奉微服務理念的設計人員老是強調微服務的 lightweight 特性,並舉出 ESB 的反例來證實微服務的優越之處。但具體實踐後就會發現,隨着微服務種類和數量愈來愈多,若是沒有服務治理系統進行支撐,微服務提倡的 lightweight 就會變成問題。主要問題有:

  • 服務路由:假設某個微服務有 60 個節點,部署在 20 臺機器上,那麼其餘依賴的微服務如何知道這個部署狀況呢?
  • 服務故障隔離:假設上述例子中的 60 個節點有 5 個節點發生故障了,依賴的微服務如何處理這種狀況呢?
  • 服務註冊和發現:一樣是上述的例子,如今咱們決定從 60 個節點擴容到 80 個節點,或者將 60 個節點縮減爲 40 個節點,新增或者減小的節點如何讓依賴的服務知道呢?

若是以上場景都依賴人工去管理,整個系統將陷入一片混亂,最終的解決方案必須依賴自動化的服務管理系統,這時就會發現,微服務所推崇的「lightweight」,最終也發展成和ESB 幾乎同樣的複雜程度。

相關文章
相關標籤/搜索