新啟動項目的架構設計 101
來自專欄文火慢燉
留在草稿箱很久的一片文章,剛好最近有了些新的實踐,就發出來了。
bliki: MonolithFirst上文中提及了兩個現象:
Almost all the successful micro service stories have started with a monolith that got too big and was broken up
Almost all the cases where I』ve heard of a system that was built as a micro service system from scratch, it has ended up in serious trouble.
其實文章中也大致歸結了原因,有兩個:
- 首先不確定你的產品是否會被用戶喜歡,這個時候其實你需要更快速的將項目完成最小功能,然後投入市場檢驗,而微服務本身就是有成本的,對於短期內的快速交付沒有幫助
- 其次,產品形態不確定的情況下,就沒有辦法有明確的邊界,也就沒有辦法設計出比較好的服務拓撲,然而微服務拓撲一旦形成,後續重構的成本是超出想像的
最近負責了一個相對複雜的產品的設計,從一開始的設計原則就是:「面向未來服務拆分構建單體應用」,所以在最一開始結合產品功能進行和模塊劃分以及拓撲設計,按照如下規則:
- 每個模塊管理自己的 DB 和 Cache,禁止跨模塊訪問 DB 和 Cache
- 上層對於下層,或者同層模塊之間的調用只能通過模塊的 API
- 禁止下層調用上層,通信依賴於隊列或者消息
- UI 層面的拼接通過最上層的 Handler 完成
- 鑒權邏輯通過中間件實現
當時考慮的點如下:
- 禁止了跨模塊存儲訪問,避免了 Schema 變更或者存儲選型變化引起不可用
- 通過 API 調用,方便後續進行服務的拆分
- UI 層面單獨抽離,方便後面進行 UI 和具體功能邏輯的拆分,也能在 UI 層實現 Module 的復用,避免大量填充 Module 的代碼出現,同時拼接邏輯放到 最上層,避免請求次數放大
鑒權通過中間件實現,後續拆分成微服務之後,需要進一步前置到 Gateway,減少 Auth 服務的請求次數,因為該服務是整個系統最關鍵且不可降級的部分,所以需要盡量減少壓力
除了上述限制以外,還引入了 Protobuf,吐出數據給客戶端以及日誌都會採用 pb 進行序列化,好處是方便欄位管理,同時 pb 兼容生成 json,順便也能降低書寫成本,不用寫一堆 `json:"xxxx"` 的 `struct tag`。
文章隨後又說到了從頭構建系統的四種套路:
1、仔細設計一個單體應用,留意軟體模塊劃分,包括API邊界和數據存儲方式。做好這些工作後,向微服務切換就相對簡單了。
2、開始時採用單體架構,然後逐步從系統邊緣剝離出微服務。3、首先構建一個單體架構作為「[犧牲架構(SacrificialArchitecture)](bliki: SacrificialArchitecture)」,然後整個的替換掉。4、以幾個粒度較大的服務開始,待功能邊界穩定後再分解成細粒度的服務。
提到的第一種就是我這個項目提到的方法,但是隨後 martin 說了一句:
However I』d feel much more comfortable with this approach if I』d heard a decent number of stories where it worked out that way.
嗯,其實就是他是對這種方案沒有信心的,注釋中提到因為他覺得不是任何一個系統都能拆分成微服務,這種上來就假設拆分成微服務的思路是有問題的。
當然啦,為什麼我卻用了這種方法呢,其實是因為我明確的知道這個系統可以拆分成微服務,基於經驗。
當我們接觸到一個自己並不是非常熟悉的系統或者領域的時候,確實不能在假設可以拆分成微服務的前提下,去設計系統,萬一未來不能很好的劃定邊界,提早的拆分其實會給以後的靈活性大打折扣。
綜上,新建立一個系統的時候,最好的方式不是從微服務開始,原因如下:
- 無法確定較好的邊界劃分方式,而一旦倉促決定,後續重構成本遠高於單體應用
- 伴隨系統建立過程中,需要花費大量工作在協議編寫,介面定義上,影響開發進度
- 分散式系統聯調、Debug 的難度都高於單體應用,需要配套監控、部署、最終一致性等相關的設施
微服務架構本身是一件奢侈品,本身會帶來的在研發,管理的成本就很高,應該把他作為團隊逐漸變得非常複雜後,不得不考慮的一種架構方案,而不應該作為 start up 項目的推薦方案。
為什麼說是「團隊逐漸變複雜」而不是「系統逐漸變複雜」呢?因為如果是系統逐漸變複雜的情況下,無論是單體還是微服務,都需要你對於邊界有個相對清晰的劃分和理解,此時單純的引入微服務架構,並不能解決根本的問題。只有當團隊逐漸變複雜之後,微服務架構更多是通過服務之間物理上的隔離,提高了團隊將整個項目變成大雜燴的門檻。
推薦閱讀: