架構

一文看齊,微服務的歷史與陷阱

微服務是近幾年非?;馃岬募軜嬙O計理念,大部分人認為是MartinFlower提出了微服務概念,但事實上微服務概念的歷史要早得多,也不是Martin Flower創造出來的,Martin只是將微服務進行了系統的闡述。不過不能否認Martin在推動微服務火熱起來的作用,微服務能火,Martin功不可沒。

參考維基百科英文版,我們簡單梳理一下微服務的歷史:

  • 2005年:Dr. PeterRodgers在Web ServicesEdge大會上提出了“Micro-Web-Services”的概念。
  • 2011年:一個軟件架構工作組使用了“microservice”一詞來描述一種架構模式。
  • 2012年:同樣是這個架構工作組,正式確定用“microservice”來代表這種架構。
  • 2012年:ThoughtWorks的James Lewis針對微服務概念在QCon San Francisco 2012發表了演講。
  • 2014年:James Lewis和Martin Flower合寫了關于微服務的一篇學術性的文章,詳細闡述了微服務。

由于微服務的理念中也包含了“服務”的概念,而SOA中也有“服務”的概念,我們自然而言地會提出疑問:微服務與SOA是什么關系,有什么區別,為何有了SOA還要提微服務?這幾個問題是理解微服務的關鍵,否則如果只是跟風拿來就用,既不會用,也用不好,用了不但沒有效果,反而還可能有副作用。

微服務與SOA的關系

對于了解過SOA的人來說,第一次看到微服務這個概念肯定會有所疑惑:為何有了SOA還要提微服務呢?等到簡單看完微服務的介紹后,很多人可能就有一個疑惑:這不就是SOA嗎?

關于SOA和微服務的關系和區別,大概分為幾個典型的觀點。

  • 微服務是SOA的實現方式

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

  • 微服務是去掉ESB后的SOA

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

  • 微服務是一種和SOA相似,但本質上不同的架構理念

如下圖所示,這種觀點認為微服務和SOA只是有點類似,但本質上是不同的架構設計理念。相似點在于下圖中交叉的地方,就是兩者都關注“服務”,都是通過服務的拆分來解決可擴展性問題。本質上不同的地方在于幾個核心理念的差異:是否有ESB、服務的粒度、架構設計的目標等。

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

  • 服務粒度

整體上來說,SOA的服務粒度要粗一些,而微服務的服務粒度要細一些。例如,對一個大型企業來說,“員工管理系統”就是一個SOA架構中的服務;而如果采用微服務架構,則“員工管理系統”會被拆分為更多的服務,比如“員工信息管理”“員工考勤管理”“員工假期管理”“員工福利管理”等更多服務。

  • 服務通信

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

  • 服務交付

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

  • 應用場景

SOA更加適合于龐大、復雜、異構的企業級系統,這也是SOA誕生的背景。這類系統的典型特征就是很多系統已經發展多年,采用不同的企業級技術,有的是內部開發的,有的是外部購買的,無法完全推倒重來或進行大規模的優化和重構。因為成本和影響太大,只能采用兼容的方式進行處理,而承擔兼容任務的就是ESB。微服務更加適合于快速、輕量級、基于Web的互聯網系統,這類系統業務變化快,需要快速嘗試、快速交付;同時基本都是基于Web,雖然開發技術可能差異很大(例如,Java、C++、.NET等),但對外接口基本都是提供HTTP RESTful風格的接口,無須考慮在接口層進行類似SOA的ESB那樣的處理。
綜合上述分析,我們將SOA和微服務對比如下表所示。 

對 比 維 度SOA微  服  務
服務粒度
服務通信重量級,ESB輕量級,例如HTTP/ RESTful
服務交付
應用場景企業級互聯網

 因此,我們可以看到,SOA和微服務本質上是兩種不同的架構設計理念,只是在“服務”這個點上有交集而已,因此兩者的關系應該是第三種模式。
其實,Martin Flower在他的微服務文章中,已經做了很好的提煉: 

In short, the  microservice architectural style is an approach to developing asingle  application as a suite of small services, each running in its own process and  communicating with lightweight mechanisms, often an HTTP resource API. These  services are built around business capabilities and independently deployable  by fully automated deployment machinery.

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

通過前面的詳細分析和比較,似乎微服務本質上就是一種比SOA要優秀很多的架構模式,那是否意味著我們都應該把架構重構為微服務呢?

其實不然,SOA和微服務是兩種不同理念的架構模式,并不存在孰優孰劣,而只是應用場景不同而已。我們介紹SOA時候提到其產生歷史背景是因為企業的IT服務系統龐大而又復雜,改造成本很高,但業務上又要求其互通,因此才會提出SOA這種解決方案。如果我們將微服務的架構模式生搬硬套到企業級IT服務系統中,這些IT服務系統的改造成本可能遠遠超出實施SOA的成本。

微服務的陷阱

單純從上面的對比來看,似乎SOA一無是處而微服務無所不能,這也導致了很多團隊在實踐時不加思考地采用微服務—既不考慮團隊的規模,也不考慮業務的發展,也沒有考慮基礎技術的支撐,只是覺得微服務很牛就趕緊來實施,以為實施了微服務后就什么問題都解決了,而一旦真正實施后才發現掉到微服務的坑里面去了。
我們看一下微服務具體有哪些坑。

  • 服務劃分過細,服務間關系復雜

服務劃分過細,單個服務的復雜度確實下降了,但整個系統的復雜度卻上升了,因為微服務將系統內的復雜度轉移為系統間的復雜度了。

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

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

  • 服務數量太多,團隊效率急劇下降

微服務的“微”字,本身就是一個陷阱,很多團隊看到“微”字后,就想到必須將服務拆分得很細,有的團隊人員規模是5~6個人,然而卻拆分出30多個微服務,平均每個人要維護5個以上的微服務。

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

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

由于微服務之間都是通過HTTP或RPC調用的,每次調用必須經過網絡。一般線上的業務接口之間的調用,平均響應時間大約為50ms,如果用戶的一起請求需要經過6次微服務調用,則性能消耗就是300ms,這在很多高性能業務場景下是難以滿足需求的。為了支撐業務請求,可能需要大幅增加硬件,這就導致了硬件成本的大幅上升。

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

系統拆分為微服務后,一次用戶請求需要多個微服務協同處理,任意微服務的故障都將導致整個業務失敗。然而由于微服務數量較多,且故障存在擴散現象,快速定位到底是哪個微服務故障是一件復雜的事情。樣例如下圖所示。

Service C的數據庫出現慢查詢,導致Service C給Service B的響應錯誤,Service B?給Service A的響應錯誤,Service A給用戶的響應錯誤。我們在實際定位時是不會有圖例中這么清晰的,最開始是用戶報錯,這時我們首先會去查Service A。導致Service A故障的原因有很多,我們可能要花半個小時甚至1個小時才能發現是ServiceB返回錯誤導致的。于是我們又去查Service B,這相當于重復Service A故障定位的步驟……如此循環下去,最后可能花費了幾個小時才能定位到是Service C的數據庫慢查詢導致了錯誤。

如果多個微服務同時發生不同類型的故障,則定位故障更加復雜,如下圖所示。

Service C的數據庫發生慢查詢故障,同時Service C到Service D的網絡出現故障,此時到底是哪個原因導致了Service C返回Error給Service B,需要大量的信息和人力去排查。

  • 沒有自動化支撐,無法快速交付

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

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

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

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

如果以上場景都依賴人工去管理,整個系統將陷入一片混亂,最終的解決方案必須依賴自動化的服務管理系統,這時我們就會發現,微服務所推崇的“lightweight”,最終也發展成和ESB幾乎一樣的復雜程度。
本文節選自《從零開始學架構:照著做,你也能成為架構師》一書,電子工業出版社出版。

我還沒有學會寫個人說明!

記?。河肋h不要在MySQL中使用UTF-8

上一篇

中臺四杰與阿里往事

下一篇

你也可能喜歡

一文看齊,微服務的歷史與陷阱

長按儲存圖像,分享給朋友

ITPUB 每周精要將以郵件的形式發放至您的郵箱


微信掃一掃

微信掃一掃
海天娱乐群 德甲联赛赛程积分2019 贵州11选5精准算法 fg游乐电子美人捕鱼 申城棋牌斗地主 加拿大快乐8开奖官方吗 在线开户股票安全吗 精准单双期期中特 江西多乐彩论坛 尤文欧冠 网上兼职赚钱app