一篇帶你了解微服務 vs. 單體架構
背景
在軟件行業,微服務架構是一種重要的發展趨勢。這一趨勢,不僅僅是對企業內的IT信息系統建設,甚至在企業向數字化轉型方面,都有著深遠的影響。微服務架構與傳統的單體軟件架構代表著IT產業處理軟件開發方式的一個根本性轉變,Netflix、Google、亞馬遜等組織均已成功采用這一轉變。但是,與傳統的單體架構相比,微服務的優勢是什么呢?
微服務
介紹
微服務這個概念最早是在2011年5月威尼斯的一個軟件架構會議上討論并提出的,用于描述一些作為通用架構風格的設計原則。2012年3月在波蘭克拉科夫舉行的33rd Degree Conference大會上,Thoughtworks首席咨詢師James Lewis做了題為《Microservices - Java, the Unix Way》的演講,這次演講里James討論了微服務的一些原則和特征,例如單一服務職責、自動擴展、DDD等等。微服務架構則是由Fred George在2012年的一次會議上提出來,在大會的演講中他講解了如何分拆服務以及如何利用MQ來進行服務間的解耦,這就是最早的微服務架構雛形。而后由Martin Fowler發揚光大并且在2014年發表了一篇著名的微服務文章,這篇文章深入全面的講解了什么是微服務架構。隨后,微服務架構逐漸成為一種非常流行的架構模式,一大批的技術框架和文章涌現出來,越來越多的公司借鑒和使用微服務架構相關的技術。
架構特點
- 圍繞業務功能進行組織(organized around business capability),不再是以前的縱向切分,而改為按業務功能橫向劃分,一個微服務最好由一個小團隊針對一個業務單元來構建。
- 做產品而非做項目(product not project),不再是做完一個個項目,交付后就完工了,而是做產品,從設計編碼到產品運維,做到全過程掌控和負責,即自己構建,自己運維(you build it,you run it)。
- 智能終端加簡單通道(smart endpoints and dumb pipe),使用基于資源的API,將大量邏輯放在客戶端,而服務器端則著重于提供資源,推薦基于Web而不是在Web之后做復雜邏輯(be of the Web,not behind the Web)。
- 去中心化管理(decentralized governance),自行其是,自我管理,不必局限在一個系統里,不必圍繞著一個中心。
- 去中心化數據管理(decentralized data management),只管理和維護自己的數據,相互之間互不直接訪問彼此的數據,只通過API來存取數據。
- 基礎設施自動化(infrastructure automation),每個微服務應該關注于自己的業務功能實現,基礎設施應該盡量自動化——構建自動化、測試自動化、部署自動化、監控自動化。
- 為應對失敗而設計(design for failure),設計之初就要考慮高可靠性(high reliability)和災難恢復(disaster recover),并考慮如何著手進行錯誤監測和錯誤診斷。
- 演進式設計(evolutionary design),沒有完美的架構,唯一不變的是變化。要善于應對變化,容易改變其設計和實現,因為其小,故而易變。
架構特征
一個微服務的架構應該具有以下特征:
- 容易被替換和升級。比如以前用 Ruby快速開發的原型可以由用Java實現的微服務代替,因為服務接口沒變,所以也沒有什么影響。
- 職責獨立完整。按功能單元組織服務,職責最好相對獨立和完整,以避免對其他服務有過多的依賴和交互。
- 可選擇最適合自己的技術方案。服務性質不同會影響技術選型,比如賬戶的注冊和登錄完全可以由Ruby on Rails、Python Django這些腳本框架來實現。但是,對于音/視頻流的編解碼和處理,最好用C/C++甚至匯編語言來寫。其他的諸如數據庫的選型、ORM或MVC框架的選擇,都可以隨機應變,按照業務和技術的具體需求,根據團隊的技術棧和人員現狀選擇最適合的方案。
- 架構由層次化轉向扁平化。服務內部可以進行適當的分層,服務之間盡量扁平化,不要引入過多的層次。
架構風格
微服務可以采用多種風格,但是一個“生態系統”內存最好遵從統一的風格和要求。微服務基本上都具有以下風格:
- 短小精悍、獨立自治:只做一個業務并專注地做好它。
- 自動化部署和測試:相比大而全的單個服務,微服務會有更多的進程,更多的服務接口,更多不同的配置,如果不能將部署和測試自動化,微服務所帶來的好處將會大大遜色。
- 盡量減少運維的負擔:微服務的增多可能會導致運維成本增加,監控和診斷故障也可能更困難,所以要未雨綢繆,在一開始的設計階段,就要充分考慮如何及時地發現問題和解決問題。
- 擁抱失效與故障:微服務的高可靠性設計和防錯性設計是與生俱來的,分布在不同的機器、地域上的服務所用到的硬件和網絡等隨時可能出問題,而這些問題要對服務質量沒有任何影響。
- 每個服務都是靈活易變、可伸縮、可擴展、可組合的:微服務為應對變化提供了更多的可能,就像樂高積木,可以隨意增減組合,拼出不同的產品。
單體架構
介紹
單體架構(Monolithic Architecture)是一種將所有功能打包在一個容器中運行的設計風格,一個實例中集成了一個系統的所有功能。通過負載均衡軟件/設備實現多實例調用,單體架構比較初級,典型的三級架構,前端(Web/手機端)+中間業務邏輯層+數據庫層。單體架構的應用比較容易部署、測試, 在項目的初期,單體應用可以很好地運行。然而,隨著需求的不斷增加, 越來越多的人加入開發團隊,代碼庫也在飛速地膨脹。慢慢地,單體應用變得越來越臃腫,可維護性、靈活性逐漸降低,維護成本越來越高
架構特點
- 結構簡單,容易理解:對于開發人員而言,這是非常重要的一點。經典的分層架構已經相對比較成熟,更容易被更多的開發人員所理解和接受,學習成本也相對比較低,對團隊本身的要求也不是特別高。這不僅使得系統的設計和開發都相對比較容易,而且出錯的幾率也會相對低一些。用現在時髦的詞語說,就是“坑相對較少”,開發實現都可以“踩在踩坑人的背上前進”
- 實現數據一致性相對比較容易,通過本地事務或者分布式事務可以方便有效地保證數據一致性
- 部署簡單方便:比如這里的在線課程系統,可以方便快速地打包成WAR包,部署到Jetty或者Tomcat容器中,也可以是一個部署在IIS中的.NET解決方案。無論哪種,一次部署完成即可運行整個應用程序
- 持續集成策略的設計相對容易:基本上團隊可以根據項目的實際情況很容易地設計出持續集成方案,很多情況下,整套解決方案會放在同一個代碼庫中,根據持續集成策略,項目的持續交付也不會有太大壓力
問題
我們從目前中大型項目的業務形態、復雜度及響應速度等維度回看單體架構時可以發現它存在如下幾個問題:
- 擴展性差 很難梳理功能依賴清單,一個功能點的變更往往很難評估其影響模塊進而無法有效地組織測試,測試與發布都會需要整體部署,非常耗時。筆者早期參與過多個單體架構,個別項目代碼量上百萬,四五十號人共同開發,一個版本的迭代最少一個季度,一次部署需要近半個小時,而這還不是最糟糕的,有些單體架構的系統部署啟動就要一天的時間,這對崇尚小版本快迭代的互聯網產品幾乎是不可接受的
- 無法實現復雜業務 一個容器中實現所功能,服務耦合性高,需要極為精巧的設計。大家都了解過GoF的設計模式,但為什么實際開發中很少直接接觸?一方面框架為我們做了很多封裝,設計模式已融入了框架的最佳實踐或編碼規范之中,另一方面SOA化、微服務化讓每個模塊的代碼盡可能地簡潔明了,大家更多的工作只聚焦于業務的代碼實現,在單體架構中為了實現業務解耦可能會大量地使用裝飾器、觀察者、適配器等,這無形中又提升了開發的門檻,能否聚焦業務實現而非架構設計是衡量一種架構好差的重要標準,后續我們會看到在Serverless下極致的體現
- 技術升級困難 牽一發而動全身,無法模塊化地實現技術框架的升級。在項目生命周期內我們不可能不去升級依賴框架/類庫的版本,更有甚者會重新選擇基礎框架,比如從早期的struts到struts2再到spring mvc、spring boot,每一次變更都會傷筋動骨,但我們又不得不做,項目要可持續,試想現在還有誰會用struts或struts2呢?溫和的、可循序漸進的技術升級也是我們所期望的
- 開發效率低 每個成員都需要有完整的環境依賴,開發環境的搭建成本高,協同開發時版本沖突頻繁,一個有問題的提交可能會影響其他所有同事的開發調試。達到一定代碼量后編譯慢啟動慢,一次調試啟動可能都要5、6分鐘
- 不利于安全管理 所有開發人員都擁有全量代碼,在安全管控上存在很大風險,尤其是對用大量外包人員或新招大量開發人員的團隊。個別公司要求員工用虛擬桌面(一種集中存儲、操作受限的虛擬環境)以避免代碼外流,但這種開發體驗差、受員工抵觸,故普及度極低
總結
微服務架構與傳統的單體架構帶來的商業利益是顯著的。如果部署得當,基于微服務的架構可以幫助業務避免欠下技術債務,以及大幅提高效率的重大價值。但是微服務服務架構帶來的靈活性同時也呈現出一定的復雜性。微服務較傳統的單體架構優勢如下:
- 敏捷性:通過將功能分解到最基本的級別然后抽象相關服務,研發可以只專注于更新應用程序的相關部分。這消除了通常與單體應用程序相關的痛苦的集成過程。微服務加速了開發,將其轉變為可在數周而非數月內完成的流程。
- 效率:微服務架構可以更有效地使用代碼和底層基礎設施。通過減少運行特定應用程序所需的基礎架構數量,可以節省多達50%的成本,這種情況并不少見。
- 彈性:通過在多個服務之間分散功能,可以消除應用程序對單點故障的敏感性。從而使應用程序能夠更好地運行,減少停機時間并可按需擴展。
- 收益:更快的迭代和更短的停機時間可以幫助增加收益。隨著微服務的不斷改進,用戶保留和參與度也會提高