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

挑戰者V發表於2021-04-19

一、單體架構

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的版本迭代。所遇到的問題很多很多,當時在做這些設計方案的時候,有很多都沒有考慮周到,導致最後程式碼落地的時候非常糟,這些都是教訓,接下來我會將這些教訓一一總結然後分享出去。

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

相關文章