從單體架構到分佈式微服務架構的思考

一、單體架構

1.什麼是單體架構?

單體架構也可叫單體系統或單體應用,是一種把系統所有的功能模塊耦合在一個應用的架構方式。

2.單體架構的優缺點有哪些?

(1)優點

  • 部署簡單
  • 技術單一
  • 用人成本相對低
  • 項目管理相對較易
  • 測試相對簡單直觀
  • 應用開發相對簡單
  • 橫向擴展容易

(2)缺點

  • 項目過於臃腫,bug難以迅速定位
  • 資源無法隔離(某個功能模塊對應的接口訪問量大,直接會影響整體性能);
  • 無法靈活擴展
  • 交付周期長(需求->設計->開發->測試->現場實施部署,就傳統性質的企業而言);
  • 部署消耗時間長
  • 可靠性差
  • 受技術棧限制
  • 可伸縮性差
  • 複雜度高

3.單體架構的技術選型有哪些?

從Java的角度看,有Spring全家桶一站式解決方案和相關的生態比較豐富(國外有GitHub,國內有Gitee,相應的開源框架非常多)。
從PHP的角度看,PHP是Web開發中最好的語言(至於為什麼說它是Web開發中最好的語言,我想原因有三個,第一個是通吃方案(網站開發、App後端、小程序等);第二個許多國內外的網站建設都是基於PHP,早期的淘寶也是如此;第三個容易上手。)

所有的技術選型都離不開一個基本的原則,那就是業務,分佈式微服務技術選型也不例外,技術服務於業務,合適的技術框架對業務支撐非常關鍵。我在2020年的寫過這樣一篇文章,其中關於對技術的思考提到過,感興趣的朋友可以閱讀這篇文章:2020年的一些思考和總結

(1)那麼關於技術選型要注重哪些因素呢?

  • 業務相關性
  • 框架流行度
  • 學習曲線
  • 文檔
  • 社區支持
  • 單元測試
  • 可擴展性
  • 許可證

(2)在(1)的基礎上舉例進行說明

以我曾經在某創業公司對EduSoho二次開發為例:
從業務相關性的角度,當時我們做的是編程教育項目,EduSoho是一個在線教育解決方案,業務性與我們完美契合。
從框架流行度,EduSoho是基於PHP開發,前面我提到過PHP是Web開發最好的語言,而EduSoho使用的PHP框架是Symfony,Symfony的框架流行度,以GitHub下圖為例說明:

從中可以看出該框架非常流行,start非常多。
從學習曲線來看,我覺得Symfony還是蠻簡單,感興趣的朋友,可以參考我這篇文章學習:
Symfony之入門學習
只要熟悉Symfony,二次開發EduSoho並不難。
從文檔上來看,Symfony框架資料非常多(網上有各種各樣的博文),對應的EduSoho官網方面的資料也非常多。
從社區支持上來看,如果Symfony出現任何問題,通過搜索引擎不能解決的話,可以去GitHub給開源維護者提issue,詳細說明問題,一般都能得到回答(前提把問題說清楚,英文不會也不怕,可以藉助翻譯工具)。
從單元測試上來看,Symfony本身就支持單元測試,不僅僅是PHP相關的框架,Java和Go對應的Web開發框架均支持單元測試。
從可擴展性上來看,Symfony發展至今能有這麼多關注(前面的Github截圖),說明國內外有不少公司在用它,只要很多公司在用可擴展性自然不差(可擴展性指能適應業務的變化)。
從許可證上來看,EduSoho減少當時我們編程教育項目的從0到1開發的時間,只要項目能夠盈利,花錢買許可證也是沒問題的,結果我們在C城果然拿下了第一筆訂單。

4.前面提到的單體架構的缺點(也可叫短板)該如何應對呢?

用組件化就能解決這個單體架構的缺點。

(1)什麼是組件化?它的目的是什麼?

組件化是一種高效的處理複雜應用系統,更好的明確功能模塊作用的方式。目的是為了解耦,把複雜系統拆分成多個組件,分離組件邊界和責任,便於獨立升級和維護。

(2)組件化的實際例子有哪些?

這裡只列舉兩個例子(實際的例子非常多):

  • 曾在某創業公司做VsCode二次開發時,當時寫的各種VsCode插件,其實也是一種組件化的體現(本質上都是為了解耦,避免大量的代碼耦合混雜)。
  • 曾在某教育公司做前後端開發的時候,前端當時使用的是React框架,那個時候我也是第一次使用React,React的組件化,讓我可重用大量的代碼(這種可重用很少出問題,除非組件本身寫的就有問題),最後不到一天就寫某個大功能模塊,使我能更好的專註於後端接口的編寫和調試。

(3)有的朋友可能會問:」新的項目我可以最開始通過組件化來避免單體架構的短板,但是老項目該怎麼辦呢?」

我的回答是只能慢慢來,一點點慢慢抽取出來(一定要在讀懂代碼的前提下進行),封裝為組件,組件可按照功能區分(公共組件、通信組件、日誌組件、權限組件、具體業務組件等)。
另外還有一點,二次開發和老項目的組件化是相通的,如下:

  • 項目先運行起來(不管是二次開發還是新到一家公司,這個流程是繞不開的);
  • 整體了解項目架構並熟悉對應的業務知識
  • 整體了解項目結構(每個包下面的代碼功能職責是什麼);
  • 整體了解數據庫表(可以間接和前面的業務知識對應起來);
  • 跑起來後,通過調用接口,逐步的去了解對應的代碼是做什麼的
  • 為了保持原本的代碼分支完整性,通過版本控制工具新建分支做實驗
  • 虛心請教,學會提問(如果是開源項目請教對應的開源維護者,如果是老項目,請教對應的老員工,在此之前一定要有自己的思考,而不是眼睛一看不到10秒,就說看不懂,這種提問是萬萬不行的)。

二、分佈式微服務架構

1.什麼是分佈式微服務架構?

(1)分佈式是什麼?為什麼要用分佈式?分佈式要考慮哪些問題?

分佈式是指數據和程序可以不位於一個服務器上,而是分散到多個服務器,以網絡上分散分佈的地理信息數據及受其影響的數據庫操作為研究對象的一種理論計算模型。

之所以要用分佈式,最關鍵的是服務器性能問題,單台服務器性能比較有限,綜合利用多台服務器,能夠提高整體的性能。

分佈式要考慮的問題有如下:

  • 如何合理的拆分出子系統
  • 子系統之間如何通信
  • 通信過程的安全如何保障
  • 子系統擴展要如何設計
  • 子系統的可靠性要如何保證
  • 多個子系統之間相互通信交互數據,如何保證數據的一致性

簡而言之可以概括為兩大問題,一個是數據的一致性,另一個是服務的穩定性。

(2)集群是什麼?為什麼要集群?集群需要考慮哪些問題?

集群是指一組獨立的計算機系統構成的一個松耦合的多處理器系統,它們之間通過網絡實現進程間的通信。應用程序可以通過網絡共享內存進行消息傳送,實現分佈式計算機。通俗一點來說,就是讓若干台計算機聯合起來工作(服務),可以是並行的,也可以是做備份。

之所以要集群,是因為如下三個方面:

  • 並發處理能力有限
  • 容錯率低,一旦服務器故障,整個服務無法訪問
  • 單台服務器計算能力低,無法完成複雜的海量數據計算

集群需要考慮哪些問題(最關鍵的是:是否有必要集群)?

  • Session共享(用戶鑒權一次,而不是每次輪詢後都要再鑒權);
  • Job(定時任務只執行一次而不是每台都執行);
  • DB數據同步
  • Cache同步
  • 集群下的各個服務器性能(CPU、磁盤、內存等);
  • 應用服務故障切換的時間
  • 軟硬件的集群管理和監控
  • 成本

(3)分佈式和集群的區別是什麼?

  • 分佈式是指將不同的業務分佈在不同的地方
  • 集群指的是將多台服務器集中在一起,實現同一業務
  • 分佈式的每一個節點,都可以做集群,而集群並不一定就是分佈式的

(4)微服務架構是什麼?

微服務架構指的是將大型複雜系統按功能或者業務需求垂直切分成更小的子系統,這些子系統以獨立部署的子進程存在,它們之間通過輕量級的、跨語言的同步(比如REST,gRPC)或者異步(消息)網絡調用進行通信。

2.微服務架構的優缺點

(1)優點
  • 複雜度可控
  • 獨立按需擴展
  • 技術選型靈活
  • 容錯可用性高
(2)缺點
  • 多服務增加運維難度
  • 系統部署依賴
  • 服務間的通信成本
  • 數據一致性
  • 系統集成測試
  • 性能監控

3.分佈式微服務的技術選型有哪些?

對於Java而言技術選型組合如下:

  • SpringBoot+SpringCloud
  • SpringBoot+SpringCloud Alibaba
  • SpringBoot+Dubbo

上面這三種是比較常見的。
當然了,分佈式微服務的技術選型不局限某一類編程語言。
以我當初在某創業公司做的編程教育平台項目為例,涉及的編程語言就有四個,分別為Python、Java、PHP、JavaScript(Node.js、Vue.js、TypeScript等)。至於這些編程語言所涉及的框架組件就更多了。對我在創業公司做項目經歷感興趣的朋友可以閱讀我的這篇文章:一位北漂在創業公司的兩年

三、總結

從單體架構到分佈式微服務架構,基本上我都參與了,有從0到1,也有二次開發,還有從1到2再到3的版本迭代。所遇到的問題很多很多,當時在做這些設計方案的時候,有很多都沒有考慮周到,導致最後代碼落地的時候非常糟,這些都是教訓,接下來我會將這些教訓一一總結然後分享出去。

最後此次本文說的內容相對比較全和雜,沒有就某一個具體中心點進行深入地講解,後面將會有系列文章就上面所涉及的內容點進行深入詳細地講解。