微服務架構在軟件行業(yè)已成為一種發(fā)展趨勢,微服務架構與傳統的單體軟件架構代表著IT產業(yè)處理軟件開發(fā)方式的一個根本性轉變。那么微服務架構與傳統的單體架構相比,有何區(qū)別呢?我們從以下幾點來看:
 

一、單體架構

單體架構,是指將開發(fā)好的項目打成war包,然后發(fā)布到tomcat等容器中的應用。
 
假設你正準備開發(fā)一款與Uber和滴滴競爭的出租車調度軟件,經過初步會議和需求分析,你可能會手動或者使用基于Spring Boot、Play或者Maven的生成器開始這個新項目,它的六邊形架構是模塊化的 ,架構圖如下:

8年Java老司機講解——微服務架構VS單體架構

 
 
應用核心是業(yè)務邏輯,由定義服務、領域對象和事件的模塊完成。圍繞著核心的是與外界打交道的適配器。適配器包括數據庫訪問組件、生產和處理消息的消息組件,以及提供API或者UI訪問支持的web模塊等。
 
盡管也是模塊化邏輯,但是最終它還是會打包并部署為單體式應用。具體的格式依賴于應用語言和框架。例如,許多Java應用會被打包為WAR格式,部署在Tomcat或者Jetty上,而另外一些Java應用會被打包成自包含的JAR格式,類似的,Rails和Node、js會被打包成層級目錄。
 
這種應用開發(fā)風格很常見,因為IDE和其它工具都擅長開發(fā)一個簡單應用,這類應用也很易于調試,只需要簡單運行此應用,用Selenium鏈接UI就可以完成端到端測試。
 
單體式應用也易于部署,只需要把打包應用拷貝到服務器端,通過在負載均衡器后端運行多個拷貝就可以輕松實現應用擴展。在早期這類應用運行的很好。
 
單體架構存在的問題:

復雜性高

 
以某個百萬行級別的單體應用xxx為例,整個項目包含的模塊非 常多,模塊的邊界模糊、依賴關系不清晰、代碼質量參差不齊、 混亂地堆砌在一起,整個項目非常復雜。每次修改代碼都心驚膽 戰(zhàn),甚至添加一個簡單的功能,或者修改一個Bug都會帶來隱含 的缺陷。

 技術債務

隨著時間推移、需求變更和人員更迭,會逐漸形成應用程序的技術債務, 并 且越積越多。“不壞不修”,這在軟件開發(fā)中非常常見,在單體應用中這種 思想更甚。已使用的系統設計或代碼難以被修改,因為應用程序中的 其他 模塊可能會以意料之外的方式使用它。

部署頻率低

隨著代碼的增多,構建和部署的時間也會增加。而在單體應用中,每次功能 的變更或缺陷的修復都會導致需要重新部署整個應用。全量部署的方式耗時 長、影響范圍大、風險高,這使得單體應用項目上線部署的頻率較低。而部 署頻率 低又導致兩次發(fā)布之間會有大量的功能變更和缺陷修復,出錯概率 比較高。

可靠性差

某個應用Bug,例如死循環(huán)、00M等,可能會導致整個應用的崩潰。

擴展能力受限

單體應用只能作為一個整體進行擴展,無法根據業(yè)務模塊的需要進行伸縮。例如,應用中有的模塊是計算密集型的,它需要強勁的 CPU ;有的模塊則是  IO 密集型的,需要更大的內存。由于這些模塊部署在一起,不得不在硬件 的選擇上做出妥協。

阻礙技術創(chuàng)新

單體應用往往使用統一的技術平臺或方案解決所有的問題,團隊中的每個成 員都必須使用相同的開發(fā)語言和框架,要想引人新框架或新技術平臺會非常 困難。例如,一個使用 Struts 2構建的、有100萬行代碼的單體應用,如 果想要換用 Spring MVC ,毫無疑問切換的成本是非常高的。

二、什么是微服務?

 

微服務的概念源于2014年3月Martin Fowler所寫的一篇文章“Microservices”。
 8年Java老司機講解——微服務架構VS單體架構
 

 

微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協調、互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務間采用輕量級的通信機制互相溝通(通常是基于HTTP的RESTful API)。
 
每個服務都圍繞著具體業(yè)務進行構建,并且能夠被獨立地部署到生產環(huán)境、類生產環(huán)境等。另外,應盡量避免統一的、集中式的服務管理機制,對具體的一個服務而言,應根據業(yè)務上下文,選擇合適的語言、工具對其進行構建。
微服務是一種架構風格,一個大型復雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是松耦合的。每個微服務僅關注于完成一件任務并很好地完成該任務。在所有情況下,每個任務代表著一個小的業(yè)務能力。
微服務架構優(yōu)勢:
1、復雜度可控
在將應用分解的同時,規(guī)避了原本復雜度無止境的積累。每一個 微服務專注于單一功能,并通過定義良好的接口清晰表述服務邊 界。由于體積小、復雜度低,每個微服務可由一個小規(guī)模開發(fā)團 隊完全掌控,易于保持高可維護性和開發(fā)效率。
2、獨立部署
由于微服務具備獨立的運行進程,所以每個微服務也可以獨立部 署。當某個微服務發(fā)生變更時無需編譯、部署整個應用。由微服 務組成的應用相當于具備一系列可并行的發(fā)布流程,使得發(fā)布更 加高效,同時降低對生產環(huán)境所造成的風險,最終縮短應用交付 周期。
3、技術選型靈活
微服務架構下,技術選型是去中心化的。每個團隊可以根據自身 服務的需求和行業(yè)發(fā)展的現狀,自由選擇最適合的技術棧。由于 每個微服務相對簡單,故需要對技術棧進行升級時所面臨的風險 就較低,甚至完全重構一個微服務也是可行的。
4、容錯
當某一組建發(fā)生故障時,在單一進程的傳統架構下,故障很有可 能在進程內擴散,形成應用全局性的不可用。在微服務架構下, 故障會被隔離在單個服務中。若設計良好,其他服務可通過重試、 平穩(wěn)退化等機制實現應用層面的容錯。
5、擴展
單塊架構應用也可以實現橫向擴展,就是將整個應用完整的復制 到不同的節(jié)點。當應用的不同組件在擴展需求上存在差異時,微 服務架構便體現出其靈活性,因為每個服務可以根據實際需求獨 立進行擴展。
微服務架構示例:
 
 

8年Java老司機講解——微服務架構VS單體架構

三、微服務架構VS單體架構

 

1.分工不同

 

以前我們通常是一個有規(guī)模的團隊圍繞一個單體應用工作,可能是一人一個模塊;微服務架構可以為軟件開發(fā)提供不同的方法,把傳統模式下的單體應用拆分成獨立的服務,從而可以單獨開發(fā)、單獨部署、單獨維護,在微服務架構下可能是一人一個系統。

 

2. 存儲方式不同

 

單體架構所有的模塊都共用一個數據庫,存儲方式比較單一,微服務每個模塊都可以使用不同的存儲方式(比如有的用redis,有的用mysql等),數據庫也是單個模塊對應自己的數據庫。
 
3.部署方式不同

 

在單體應用中,每次功能 的變更或缺陷的修復都會導致需要重新部署整個應用。微服務架構服務可獨立部署,并且可以獨立于其他服務進行擴展,如果部署得當,基于微服務的架構可以幫助業(yè)務避免欠下技術債務,以及大幅提高效率的重大價值。
 
4.容災不同

 

當某一組建發(fā)生故障時,在單一進程的傳統架構下,故障很有可 能在進程內擴散,形成應用全局性的不可用。在微服務架構下, 故障會被隔離在單個服務中。好的微服務可以隔離故障避免服務整體down掉,壞的微服務設計仍然可以因為一個子服務出現問題導致連鎖反應。

 

5. 開發(fā)模式不同

 

單體架構所有的模塊開發(fā)所使用的技術一樣,開發(fā)模式比較受限,微服務每個模塊都可以使用不同的開發(fā)技術,開發(fā)模式更靈活。
 
使用微服務架構,能提升效率,有利于技術創(chuàng)新,已受到越來越多開發(fā)者的青睞。