一些微服务拆分的浅见
大家好,我是Z哥。
不管是十幾年前 SOA 的流行,還是 7、8 年前微服務(wù)的大行其道,還是如今云原生的展露鋒芒,背后都離不開一件事,程序拆分或者說(shuō)服務(wù)拆分。否則,一個(gè)單體應(yīng)用,以上的這些技術(shù)潮流好像都與它沒什么關(guān)系,只是一個(gè)看客。
雖然Z哥我沒有從頭開始完整地親歷過(guò)以上三個(gè)時(shí)期,但是這三個(gè)時(shí)期都有過(guò)我留下的足跡。所以我想我接下去分享的內(nèi)容應(yīng)該對(duì)處在云原生時(shí)代的大家有所幫助。
/01? 拆分有什么好處/
拆分的目的很容易理解,分而治之。本質(zhì)是將復(fù)雜的大問(wèn)題分解成更簡(jiǎn)單的多個(gè)小問(wèn)題,從而解決它。
而在拆分之前的單體系統(tǒng)中,我們往往面臨著哪些問(wèn)題呢?
01? 數(shù)據(jù)庫(kù)瓶頸
所有的業(yè)務(wù)都由一個(gè)數(shù)據(jù)庫(kù)承載著,隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)庫(kù)日常內(nèi)存吃緊,時(shí)不時(shí)還搞出個(gè) cpu 90% + 以示它的怒火。
02? 增加人員對(duì)開發(fā)效率提升的邊際效益遞減
項(xiàng)目里的代碼量從 10 萬(wàn)行,增長(zhǎng)到 100 萬(wàn),再到 1000 萬(wàn)。隨著代碼量的增加,代碼之間的耦合問(wèn)題越發(fā)嚴(yán)重,開發(fā)效率明顯降低。好吧,效率不夠數(shù)量來(lái)湊。擴(kuò)招了更多的人進(jìn)來(lái),但是發(fā)現(xiàn)耦合問(wèn)題更加嚴(yán)重了,經(jīng)常出現(xiàn) A 等 B 提交代碼,B等 C 提交代碼,C 等 A 提交代碼的情況……
03? 運(yùn)維成本指數(shù)級(jí)增加
隨著項(xiàng)目參與人員的增加,每天發(fā)布程序的次數(shù)也增加了。可怕的是,代碼量也在增加,導(dǎo)致每次編譯發(fā)布的時(shí)間也增加了,這對(duì)開發(fā)效率來(lái)說(shuō)是雙重打擊。每天發(fā)布的時(shí)間加起來(lái)可能就占了半天。
希望你所在的團(tuán)隊(duì)不要處在如此痛苦的場(chǎng)景中。
/02 ?什么時(shí)候拆?/
拆分雖好,但也不是萬(wàn)能的靈丹妙藥。對(duì)于大多數(shù)組織來(lái)說(shuō),一個(gè)新系統(tǒng)不適合一上來(lái)就按照拆分的思路來(lái)做。因?yàn)椴鸱中枰趯?duì)當(dāng)前業(yè)務(wù)、當(dāng)前系統(tǒng)、當(dāng)前環(huán)境的理解之上的,而面對(duì)一個(gè)未來(lái)充滿未知的新業(yè)務(wù),我們當(dāng)下的信息積累是不夠的,如果過(guò)早拆分,很容易導(dǎo)致邊界劃分不合理的情況,這在后續(xù)會(huì)帶來(lái)不小的負(fù)面作用。甚至,可能這個(gè)產(chǎn)品在經(jīng)過(guò)市場(chǎng)驗(yàn)證失敗后就被砍了,之前的工作做得再多、再完美,全白費(fèi)了。
因此相對(duì)來(lái)說(shuō),從一個(gè)已有的單體系統(tǒng)中逐步拆分出一個(gè)個(gè)模塊反而容易得多,因?yàn)榇_定性更高。
單體系統(tǒng)和分布式系統(tǒng)對(duì)成本與業(yè)務(wù)復(fù)雜度之間的關(guān)系是這樣的。
因此,在這個(gè)臨界點(diǎn)附近進(jìn)行拆分工作的性價(jià)比是最高的。
對(duì)于如何判斷是否達(dá)到了這個(gè)臨界點(diǎn),我認(rèn)為至少要符合以下三點(diǎn)中的兩點(diǎn)。
業(yè)務(wù)已在市場(chǎng)站穩(wěn)腳跟,規(guī)劃中業(yè)務(wù)發(fā)展速度未來(lái)可能會(huì)加速。
開發(fā)人員持續(xù)擴(kuò)張,并且未來(lái)還將繼續(xù)。
平均單人開發(fā)效率下降。多個(gè)開發(fā)人員之間的工作相互影響、依賴,導(dǎo)致解決這些沖突所花費(fèi)的成本占到了總開發(fā)成本的 30%以上。比如,提交的代碼沖突、你等我 coding 完才能繼續(xù) coding 這種(往往這樣的情況下,每個(gè)迭代的版本也很大)。
/03? 拆分前的準(zhǔn)備工作/
并不是以上條件滿足了就可以拆了。在實(shí)際拆分之前,我們要做一些準(zhǔn)備工作。這其中最為關(guān)鍵的是兩件事:
統(tǒng)一拆分原則
基礎(chǔ)設(shè)施建設(shè)
因?yàn)閺膯误w系統(tǒng)到分布式系統(tǒng)不僅僅是技術(shù)的升級(jí),更是開發(fā)理念的轉(zhuǎn)變。
這兩件事的具體就不展開了,前人已經(jīng)總結(jié)過(guò)很多了,我就簡(jiǎn)單羅列一下。在應(yīng)用拆分這件事上比較適用的是:
高內(nèi)聚低耦合
閉包原則
接口隔離
演進(jìn)思維
避免循環(huán)依賴
另外,分布式系統(tǒng)中常用的基礎(chǔ)設(shè)施主要是以下這些:
消息隊(duì)列
緩存
日志系統(tǒng)
服務(wù)治理
監(jiān)控
網(wǎng)關(guān)
配置中心
數(shù)據(jù)訪問(wèn)組件
以上這些是必須項(xiàng),其它可選項(xiàng)還有不少,比如:分布式文件系統(tǒng)、容器管理平臺(tái)、CI/CD 等等。
/04? 拆分思路/
具體的拆分其實(shí)就是劃分邊界的過(guò)程。強(qiáng)烈建議通過(guò) DDD 的思想進(jìn)行。
深入理解業(yè)務(wù),從中定義出隱含的實(shí)體、值對(duì)象。
從實(shí)體對(duì)象中找出聚合根,根據(jù)實(shí)體、值對(duì)象與聚合根的依賴關(guān)系,建立聚合。
根據(jù)業(yè)務(wù)場(chǎng)景等環(huán)境因素,劃分限界上下文。這里的限界上下文就可以與拆分出來(lái)的微服務(wù)一一對(duì)應(yīng)。
其中最關(guān)鍵的是「抽象」工作,為了更易理解還是來(lái)舉個(gè)例子說(shuō)一下。比如,當(dāng)我們?cè)谀衬仇B(yǎng)車平臺(tái)下單一個(gè)保養(yǎng)訂單,你說(shuō)其中的“安裝”業(yè)務(wù)該以什么形式進(jìn)行交易比較合理?Z哥我認(rèn)為是將其當(dāng)作一個(gè)普通商品看待,當(dāng)然該平臺(tái)也的確是這么做的。如此一來(lái),購(gòu)買機(jī)油機(jī)濾和安裝服務(wù)對(duì)用戶來(lái)說(shuō)是一樣的,很自然地被創(chuàng)建在一筆訂單里,而不是兩筆訂單。
如何評(píng)估抽象的好不好呢?可以從以下兩個(gè)角度來(lái)觀察。
兩個(gè)限界上下文之間的依賴應(yīng)該越少越好。并且依賴的上游不需要知道下游的信息。比如訂單 service 依賴商品 service ,但是商品 service 無(wú)需知道訂單 service 的存在。
推演可能的未來(lái)業(yè)務(wù),如果能響應(yīng)業(yè)務(wù)變化(不一定 100%滿足),則證明該抽象是符合未來(lái)預(yù)期的,可以在一段時(shí)間內(nèi)支撐業(yè)務(wù)的持續(xù)發(fā)展。
不過(guò)不管怎樣,最終你都在抽象程度、成本、復(fù)用性這三者之間平衡。
除此之外,我們還可以根據(jù)以下三個(gè)維度來(lái)進(jìn)行拆分。
是否經(jīng)常變動(dòng)
復(fù)用程度的高低
是否有特殊的要求(高性能、安全性等)
好了,總結(jié)一下。
這篇呢,Z哥和你分享了我對(duì)微服務(wù)或者說(shuō)分布式系統(tǒng)如何拆分的看法。
拆分可以解決單體系統(tǒng)的三個(gè)痛點(diǎn)。
數(shù)據(jù)庫(kù)瓶頸。
增加人員對(duì)開發(fā)效率提升的邊際效益遞減
運(yùn)維成本指數(shù)級(jí)增加。
但是拆分也不是越早越好,至少符合以下三點(diǎn)中的兩點(diǎn)。
業(yè)務(wù)已在市場(chǎng)站穩(wěn)腳跟,規(guī)劃中業(yè)務(wù)發(fā)展速度未來(lái)可能會(huì)加速。
開發(fā)人員持續(xù)擴(kuò)張,并且未來(lái)還將繼續(xù)。
平均單人開發(fā)效率下降。多個(gè)開發(fā)人員之間的工作相互影響、依賴,導(dǎo)致解決這些沖突所花費(fèi)的成本占到了總開發(fā)成本的 30%以上。比如,提交的代碼沖突、你等我 coding 完才能繼續(xù) coding 這種(往往這樣的情況下,每個(gè)迭代的版本顆粒度不得不變得很大)。
然后,拆分前還需要做好兩項(xiàng)準(zhǔn)備工作。
統(tǒng)一拆分原則
基礎(chǔ)設(shè)施建設(shè)
具體實(shí)施拆分的思路,建議以 DDD 的思想來(lái)進(jìn)行。
其實(shí)任何事都沒有一招鮮吃遍天的方法,隨著業(yè)務(wù)、技術(shù)的發(fā)展,我們的拆分思路也需要持續(xù)迭代。如果你之前這方面的實(shí)戰(zhàn)經(jīng)驗(yàn)比較缺乏,不妨從我分享的這些方面入手試試,希望能對(duì)你有所幫助。
推薦閱讀:
接手歷史悠久的老項(xiàng)目,干or跑?
如何讓自己更自律
原創(chuàng)不易,如果你覺得這篇文章還不錯(cuò),就「點(diǎn)贊」或者「在看」一下吧,鼓勵(lì)我的創(chuàng)作 :)
也可以分享我的公眾號(hào)名片給有需要的朋友們。
如果你有關(guān)于軟件架構(gòu)、分布式系統(tǒng)、產(chǎn)品、運(yùn)營(yíng)的困惑
可以試試點(diǎn)擊「閱讀原文」
總結(jié)
以上是生活随笔為你收集整理的一些微服务拆分的浅见的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Blog.Core开源】快速升级.NE
- 下一篇: MassTransit中RequestR