單體的 TienChin 和微服務的 TienChin 有何異同?
有不少小伙伴希望松哥能整一個微服務的實戰項目,微服務這塊技術點其實松哥是講過很多了,圖文版的教程視頻版的教程都有,不過確實缺乏一個項目,所以我在想等 TienChin 項目搞完之后,和小伙伴們也來一起搞一個微服務的項目。
今天我想從架構的角度來和小伙伴們聊一聊微服務。不聊具體的技術點,就單純來看看一個微服務項目該怎么設計。
1. 單體版 TienChin
松哥目前在錄的 TienChin 項目就是一個前后端分離的單體項目,采用了 Spring Boot + Vue3。那么單體版的 TienChin 具有什么樣的特征呢?我從優點和缺點兩個方面來和大家分析。
先來看一張簡單的架構圖:
可以看到,雖然是單體項目,但是為了開發方便,項目也細分為許多不同的模塊,項目中的適配器可以分為兩大類:
入站適配器:就是外部系統來調用我們的系統,REST API 和 Vue 網頁都算是入站適配器,外部系統通過這兩個接口來調用我們的系統。
出站適配器:這個主要是我們系統內部調用外部系統的方式,例如我們的項目中需要用到 MySQL、Redis等,那么就通過出站適配器來實現。
1.1 優點
- 開發簡單:隨便一個 IDE,擼起袖子就可以開寫了。
- 測試簡單:項目啟動之后,直接利用 POSTMAN 等工具就可以測試項目接口了。
- 部署簡單:項目開發完成之后,打包成一個 jar 或者一個 war,直接部署就行了。
- 橫向擴展簡單:當項目并發能力不足的時候,可以方便的結合 Nginx 等負載均衡工具進行橫向擴展。
可以看到,單體項目的優勢整體上來說還是非常明顯的。
1.2 缺點
然而缺點也是非常明顯的。
- 項目越來越復雜
首先就是項目不可能一直這么簡單,我們這個項目中還是細分了很多不同的模塊。隨著時間的推移,這些模塊會變得越來愈復雜。修改每一個 BUG 都要小心翼翼,牽一發而動全身。并且隨著項目組中人員的離職/入職,新接手的人會讓這個項目更加復雜,每一次 BUG 的修復或者新功能的添加,都會讓這個項目變得更加“不可捉摸”。
- 開發進度越來越不可控
由于系統越來越復雜,我們不得不增派人手參與到這個項目的開發中,以期推進項目進度。這么多人的協調又是一個問題。并且,隨著項目越來越大,每一次編譯運行都得數分鐘、十幾分鐘甚至更久,這也會嚴重拖慢我們的項目進度。
- 發版周期過長
單體項目發版很多小伙伴可能都刻骨銘心,發版當天如臨大敵,所有人都加班,等項目上線運行都沒問題,各項數據都 OK,此時可能已經凌晨三四點了,所有人拖著疲憊的身體下班。正是由于每一次發版都是一個大事,所以一般單體項目不太會頻繁發版(我說的頻繁是指如一天一版這種),發版周期普遍比較長。
- 難以擴展
當系統不同模塊對資源的需求不同的時候,我們想做針對性的硬件擴展也并不方便。
舉個簡單例子,有一個模塊需要進行大量的運算,我們希望能為之提供更好的 CPU;有一個模塊需要更大的內存,我們需要擴展更大的內存。
然而由于所有的模塊都打包在一起,我們只能針對當前服務器做各種硬件升級,無法針對某一個模塊做專門的硬件升級。
- 過期的技術棧不易更新
我相信很多小伙伴見到的單體項目還有一個特點就是技術棧普遍比較老舊。這也是因為單體項目時間久了之后,積重難返,想要對基礎框架做版本升級往往牽一發而動全身,更別提從傳統的 SSM 切換到 Spring Boot 上這種超級繁瑣的工作了。因此大部分的單體項目,在立項的那一刻選用了什么技術棧、選用了技術的哪個版本,基本上這個項目未來都是這個版本了。
從上面的介紹中小伙伴們可以看到,單體項目優點很明顯,然而缺點也是非常明顯的。而這些缺點,都可以通過微服務來解決。
2. 微服務版 TienChin
如果 TienChin 項目是微服務版呢?我們來看一張簡單的架構圖。
簡單畫了張圖,我來解釋下:
- 首先我們基本上是按照業務來劃分服務的。每一個服務都有自己獨立的數據庫,自己操作自己的庫。
- 假設在線索管理中,需要調用商機管理,那不能直接操作商機的數據庫,必須去調用商機管理服務中提供的 REST API,通過這個 REST API 來操作庫。
- 所有的服務有一個統一的入口 Gateway,如果前端是手機 App 或者小程序之類的,通過 Gateway 來訪問到系統。
- 有一個后臺管理的 Web UI 項目,提供相應的網頁操作。
大致上就是這個樣子。
那么這個微服務版的 TienChin 跟前面的單體版 TienChin 相比優勢體現在哪里呢?
- 容易維護
首先第一點就是,項目拆分為微服務之后,每個服務相對來說都比較小,項目的維護相對來說也會比較容易。一個比較小的項目,在 IDE 中啟動也會比較快。可以有一個很小的團隊來負責項目的維護。
- 服務可以自由擴展
以上圖為例,如果某日搞促銷活動,線索管理這個服務的并發量比較大,我們可以非常方便的為線索管理模塊做橫向擴展,如下圖這樣:
任何一個服務,如果有需求,都可以非常方便的進行擴展,并且可以根據服務的特點來選擇合適的硬件,例如這個服務耗內存,那就加大內存;另一個服務耗 CPU,那就選擇一個性能到位的 CPU 等等。
- 解耦后更強的容錯性
通過服務降級、熔斷等微服務組件的使用,我們可以實現各個微服務具備更強的容錯性。一個服務出故障,并不會影響其他的服務。例如合同管理里邊發生了內存泄漏,這個并不會影響到商機管理服務。
- 更容易采用新技術
之前我們在談到單體項目的弊端的時候,提到了單體項目的技術棧更新非常不易。現在我們切換成微服務了,新技術棧的切換其實就變得非常容易了。每一個微服務都可以根據當前項目的情況,選擇是否采用最新的技術棧,而且一個微服務在切換最新技術棧的過程中,如果不幸發生了問題了,也不會影響到其他的微服務,只會影響到當前的服務。由于各個微服務之間基本上都是通過 REST API 進行交互的,所以,退一萬步,你甚至可以使用不同的開發語言來開發不同的微服務。
- 更友好的 CI/CD
CI/CD 是 DevOps 的一部分,但是在前面的單體項目中,當項目比較大的時候,想做到持續交付/持續部署已經越來越難了,而微服務讓一個超大規模的項目可以非常方便的實現 CI/CD。
現在,我們的每一個服務都有自己獨立的團隊、獨立的代碼倉庫、獨立的自動化部署流水線,且互不相擾,如下圖這樣:
現在,每一個服務都可以獨立的實現服務的上線和部署,結合 DevOps 可以做到非常輕松的發版,不需要再像以前單體應用發版的時候,如臨大敵一樣。
這樣劃分之后,工程師也可以將自己的精力放在業務開發商,提供更多有價值的功能,而不是像一個救火隊員一樣,每天忙著四處滅火。
好啦,通過這樣一篇簡單的文章和圖片,希望大家對微服務有一個基本的認知,當然,微服務也不是“銀彈”,微服務架構也存在問題,這個咱們后面有空了松哥再繼續和小伙伴們分享。