一刽酱、前言
微服務(wù)在最近幾年大行其道臭蚁,很多系統(tǒng)的研發(fā)都在考慮采用微服務(wù)架構(gòu),同時(shí)肌似,隨著 Docker 容器技術(shù)和DevOps開(kāi)發(fā)運(yùn)維一體化等相關(guān)技術(shù)發(fā)展费就,微服務(wù)變得更容易管理,這為微服務(wù)架構(gòu)快速發(fā)展創(chuàng)造了有利條件锈嫩。
在落地微服務(wù)的路上受楼,拆分服務(wù)是個(gè)很熱的話(huà)題确买。我們應(yīng)該按照什么原則將現(xiàn)有的業(yè)務(wù)進(jìn)行拆分膳凝?是否拆分得越細(xì)就越好?接下來(lái)一起聊聊服務(wù)拆分的策略和原則震束。
二对雪、微服務(wù)拆分目的
不忘初心方得始終河狐。
在介紹如何拆分之前,我們需要了解下拆分的目的是什么瑟捣,這樣才不會(huì)在后續(xù)的拆分過(guò)程中忘了最初的目的馋艺。拆分的本質(zhì)是為了將復(fù)雜的問(wèn)題簡(jiǎn)單化,那么我們?cè)趩误w架構(gòu)階段遇到了哪些復(fù)雜性問(wèn)題呢迈套?
首先來(lái)回想下當(dāng)初為什么選用了單體架構(gòu)捐祠,在很多項(xiàng)目剛啟動(dòng)的時(shí)候,我們只希望能盡快地將項(xiàng)目搭建起來(lái)桑李,方便將產(chǎn)品更早的投放市場(chǎng)進(jìn)行快速驗(yàn)證踱蛀。在開(kāi)發(fā)初期窿给,這種架構(gòu)確實(shí)給開(kāi)發(fā)和運(yùn)維帶來(lái)了很大的便捷,主要體現(xiàn)在:
- 開(kāi)發(fā)簡(jiǎn)單直接率拒,代碼和項(xiàng)目集中式管理崩泡。
- 排查問(wèn)題時(shí)只需要排查這個(gè)應(yīng)用就可以了,更有針對(duì)性猬膨。
- 只需要維護(hù)一個(gè)工程角撞,節(jié)省維護(hù)系統(tǒng)運(yùn)行的人力成本。
但是隨著功能越來(lái)越多勃痴,開(kāi)發(fā)團(tuán)隊(duì)的規(guī)模越來(lái)越大谒所,單體架構(gòu)的缺陷慢慢體現(xiàn)出來(lái),主要有以下幾個(gè)方面:
- 在技術(shù)層面召耘,數(shù)據(jù)庫(kù)的連接數(shù)成為應(yīng)用服務(wù)器擴(kuò)容的瓶頸百炬,因?yàn)檫B接 MySQL 的客戶(hù)端連接數(shù)量是有限制的。
- 除此之外污它,單體架構(gòu)增加了研發(fā)的成本抑制了研發(fā)效率的提升。比如公司的垂直電商系統(tǒng)團(tuán)隊(duì)會(huì)被按業(yè)務(wù)線(xiàn)拆分為不同的組庶弃。當(dāng)如此多的小團(tuán)隊(duì)共同維護(hù)一套代碼和一個(gè)系統(tǒng)時(shí)衫贬,在配合的過(guò)程中就會(huì)出現(xiàn)問(wèn)題。
- 煙囪式重復(fù)建設(shè)歇攻。不同的團(tuán)隊(duì)之間溝通少固惯,假如一個(gè)團(tuán)隊(duì)需要一個(gè)發(fā)送短信的功能,那么有的研發(fā)同學(xué)會(huì)認(rèn)為最快的方式不是詢(xún)問(wèn)其他團(tuán)隊(duì)是否有現(xiàn)成的缴守,而是自己寫(xiě)一套葬毫,但是這種想法是不合適的,會(huì)造成功能的重復(fù)開(kāi)發(fā)屡穗。
- 由于代碼部署在一起贴捡,每個(gè)人都向同一個(gè)代碼庫(kù)提交代碼,代碼沖突無(wú)法避免村砂;同時(shí)功能之間耦合嚴(yán)重烂斋,可能你只是更改了很小的邏輯卻導(dǎo)致其它功能不可用,從而在測(cè)試時(shí)需要對(duì)整體功能回歸础废,延長(zhǎng)了交付時(shí)間汛骂。模塊之間互相依賴(lài),一個(gè)小團(tuán)隊(duì)中的成員犯了一個(gè)錯(cuò)誤评腺,就可能會(huì)影響到其它團(tuán)隊(duì)維護(hù)的服務(wù)帘瞭,對(duì)于整體系統(tǒng)穩(wěn)定性影響很大。
- 最后蒿讥,單體架構(gòu)對(duì)于系統(tǒng)的運(yùn)維也會(huì)有很大的影響蝶念。想象一下锋拖,在項(xiàng)目初期你的代碼可能只有幾千行,構(gòu)建一次只需要一分鐘祸轮,那么你可以很敏捷靈活地頻繁上線(xiàn)變更修復(fù)問(wèn)題兽埃。但是當(dāng)你的系統(tǒng)擴(kuò)充到幾十萬(wàn)行甚至上百萬(wàn)行代碼的時(shí)候,一次構(gòu)建的過(guò)程包括編譯适袜、單元測(cè)試柄错、打包和上線(xiàn)到正式環(huán)境,花費(fèi)的時(shí)間可能達(dá)到十幾分鐘苦酱,并且任何小的修改售貌,都需要構(gòu)建整個(gè)項(xiàng)目,上線(xiàn)變更的過(guò)程非常不靈活疫萤。而這些問(wèn)題都可以通過(guò)微服務(wù)化拆分來(lái)解決颂跨。
為了方便你更好的理解這塊,在此附上一份表格(內(nèi)容來(lái)源:《持續(xù)演進(jìn)的 Cloud Native:云原生架構(gòu)下微服務(wù)最佳》一書(shū))扯饶,可以更直觀地幫助你認(rèn)識(shí)拆分的目的恒削。
三、單體應(yīng)用拆分成微服務(wù)的時(shí)機(jī)
產(chǎn)品初期尾序,應(yīng)該以單體架構(gòu)優(yōu)先钓丰。因?yàn)槊鎸?duì)一個(gè)新的領(lǐng)域,對(duì)業(yè)務(wù)的理解很難在開(kāi)始階段就比較清晰每币,往往是經(jīng)過(guò)一段時(shí)間之后携丁,才能逐步穩(wěn)定,如果拆分過(guò)早兰怠,導(dǎo)致邊界拆分不合理或者拆的過(guò)細(xì)梦鉴,反而會(huì)影響生產(chǎn)力。很多時(shí)候揭保,從一個(gè)已有的單體架構(gòu)中逐步劃分服務(wù)肥橙,要比一開(kāi)始就構(gòu)建微服務(wù)簡(jiǎn)單得多。同時(shí)公司的產(chǎn)品并沒(méi)有被市場(chǎng)驗(yàn)證過(guò)掖举,有可能會(huì)失敗快骗,所以這個(gè)投入的風(fēng)險(xiǎn)也會(huì)比較高。另外塔次,在資源受限的情況下方篮,采用微服務(wù)架構(gòu)很多優(yōu)勢(shì)無(wú)法體現(xiàn),性能上的劣勢(shì)反而會(huì)比較明顯励负。如下圖所示藕溅。當(dāng)業(yè)務(wù)復(fù)雜度達(dá)到一定程度后,微服務(wù)架構(gòu)消耗的成本才會(huì)體現(xiàn)優(yōu)勢(shì)继榆,并不是所有的場(chǎng)景都適合采用微服務(wù)架構(gòu)巾表,服務(wù)的劃分應(yīng)逐步進(jìn)行汁掠,持續(xù)演進(jìn)。產(chǎn)品初期集币,業(yè)務(wù)復(fù)雜度不高的時(shí)候考阱,應(yīng)該盡量采用單體架構(gòu)。
隨著公司的商業(yè)模式逐漸得到驗(yàn)證,且產(chǎn)品獲得了市場(chǎng)的認(rèn)可跨细,為了能加快產(chǎn)品的迭代效率快速占領(lǐng)市場(chǎng)鹦倚,公司開(kāi)始引進(jìn)更多的開(kāi)發(fā)同學(xué),這時(shí)系統(tǒng)的復(fù)雜度會(huì)變得越來(lái)越高冀惭,就出現(xiàn)單體應(yīng)用和團(tuán)隊(duì)規(guī)模之間出現(xiàn)矛盾震叙,研發(fā)效率不升反降。上圖中的交叉點(diǎn)表明云头,業(yè)務(wù)已經(jīng)達(dá)到了一定的復(fù)雜度捐友,單體應(yīng)用已經(jīng)無(wú)法滿(mǎn)足業(yè)務(wù)增長(zhǎng)的需求,研發(fā)效率開(kāi)始下降溃槐,而這時(shí)就是需要考慮進(jìn)行服務(wù)拆分的時(shí)機(jī)點(diǎn)。這個(gè)點(diǎn)需要架構(gòu)師去權(quán)衡科吭。當(dāng)我們清楚了什么時(shí)候進(jìn)行拆分昏滴,就可以直接落地了嗎?不是的对人,微服務(wù)拆分的落地還要提前準(zhǔn)備好配套的基礎(chǔ)設(shè)施谣殊,如:服務(wù)接口設(shè)計(jì)(描述)、注冊(cè)中心牺弄、微服務(wù)框架選型姻几、服務(wù)監(jiān)控、服務(wù)追蹤势告、服務(wù)治理等幾大基本組件蛇捌,以上每個(gè)組件缺一不可,每個(gè)組件展開(kāi)又包括很多技術(shù)咱台,比如:持續(xù)集成络拌、容器技術(shù)、持續(xù)部署回溺、DevOps 等相關(guān)概念春贸,以及人才的儲(chǔ)備和觀念的變化混萝。微服務(wù)不僅僅是技術(shù)的升級(jí),更是開(kāi)發(fā)方式萍恕、組織架構(gòu)逸嘀、開(kāi)發(fā)觀念的轉(zhuǎn)變。
何時(shí)進(jìn)行微服務(wù)的拆分允粤,整體總結(jié)如下:
- 業(yè)務(wù)規(guī)模:業(yè)務(wù)模式得到市場(chǎng)的驗(yàn)證崭倘,需要進(jìn)一步加快腳步快速占領(lǐng)市場(chǎng),這時(shí)業(yè)務(wù)的規(guī)模變得越來(lái)越大维哈,按產(chǎn)品生命周期來(lái)劃分(導(dǎo)入期绳姨、成長(zhǎng)期、成熟期阔挠、衰退期)這時(shí)一般在成長(zhǎng)期階段飘庄。如果是導(dǎo)入期,盡量采用單體架構(gòu)购撼。對(duì)于信息化項(xiàng)目如果已建系統(tǒng)數(shù)量達(dá)到5個(gè)以上跪削,為了形成公共組件(微服務(wù))的復(fù)用,個(gè)人認(rèn)為也是考慮進(jìn)行微服務(wù)拆分的時(shí)機(jī)迂求。
- 團(tuán)隊(duì)規(guī)模:一般是團(tuán)隊(duì)達(dá)到幾十人的時(shí)候碾盐。
- 技術(shù)儲(chǔ)備:領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)、注冊(cè)中心揩局、配置中心毫玖、日志系統(tǒng)、持續(xù)交付凌盯、監(jiān)控系統(tǒng)付枫、分布式定時(shí)任務(wù)、CAP 理論驰怎、分布式調(diào)用鏈阐滩、API 網(wǎng)關(guān)等等。
- 人才儲(chǔ)備:精通微服務(wù)落地經(jīng)驗(yàn)的架構(gòu)師及在測(cè)試同學(xué)眼中只會(huì)寫(xiě)bug的開(kāi)發(fā)同學(xué)县忌。
- 研發(fā)效率:研發(fā)效率大幅下降掂榔,具體問(wèn)題參加上面拆分目的里提到的。
四症杏、拆分時(shí)指導(dǎo)原則
1. 單一服務(wù)內(nèi)部功能高內(nèi)聚低耦合
也就是說(shuō)每個(gè)服務(wù)只完成自己職責(zé)內(nèi)的任務(wù)装获,對(duì)于不是自己職責(zé)的功能交給其它服務(wù)來(lái)完成。
2. 閉包原則(CCP)
微服務(wù)的閉包原則就是當(dāng)我們需要改變一個(gè)微服務(wù)的時(shí)候鸳慈,所有依賴(lài)都在這個(gè)微服務(wù)的組件內(nèi)饱溢,不需要修改其他微服務(wù)。
3. 服務(wù)自治走芋、接口隔離原則
盡量消除對(duì)其他服務(wù)的強(qiáng)依賴(lài)绩郎,這樣可以降低溝通成本潘鲫,提升服務(wù)穩(wěn)定性。服務(wù)通過(guò)標(biāo)準(zhǔn)的接口隔離肋杖,隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié)溉仑。這使得服務(wù)可以獨(dú)立開(kāi)發(fā)、測(cè)試状植、部署浊竟、運(yùn)行,以服務(wù)為單位持續(xù)交付津畸。
4. 持續(xù)演進(jìn)原則
在服務(wù)拆分的初期振定,你其實(shí)很難確定服務(wù)究竟要拆成什么樣。從微服務(wù)這幾個(gè)字來(lái)看肉拓,服務(wù)的粒度貌似應(yīng)該足夠小后频,但是服務(wù)多了也會(huì)帶來(lái)問(wèn)題,服務(wù)數(shù)量快速增長(zhǎng)會(huì)帶來(lái)架構(gòu)復(fù)雜度急劇升高暖途,開(kāi)發(fā)卑惜、測(cè)試、運(yùn)維等環(huán)節(jié)很難快速適應(yīng)驻售,會(huì)導(dǎo)致故障率大幅增加露久,可用性降低,非必要情況欺栗,應(yīng)逐步劃分毫痕,持續(xù)演進(jìn),避免服務(wù)數(shù)量的爆炸性增長(zhǎng)迟几,這等同于灰度發(fā)布的效果镇草,先拿出幾個(gè)不太重要的功能拆分出一個(gè)服務(wù)做試驗(yàn),如果出現(xiàn)故障瘤旨,則可以減少故障的影響范圍。
5. 拆分的過(guò)程盡量避免影響產(chǎn)品的日常功能迭代
也就是說(shuō)要一邊做產(chǎn)品功能迭代竖伯,一邊完成服務(wù)化拆分存哲。比如優(yōu)先剝離比較獨(dú)立的邊界服務(wù)(如短信服務(wù)等),從非核心的服務(wù)出發(fā)減少拆分對(duì)現(xiàn)有業(yè)務(wù)的影響七婴,也給團(tuán)隊(duì)一個(gè)練習(xí)祟偷、試錯(cuò)的機(jī)會(huì)。同時(shí)當(dāng)兩個(gè)服務(wù)存在依賴(lài)關(guān)系時(shí)優(yōu)先拆分被依賴(lài)的服務(wù)打厘。
6. 服務(wù)接口的定義要具備可擴(kuò)展性
服務(wù)拆分之后修肠,由于服務(wù)是以獨(dú)立進(jìn)程的方式部署,所以服務(wù)之間通信就不再是進(jìn)程內(nèi)部的方法調(diào)用而是跨進(jìn)程的網(wǎng)絡(luò)通信了户盯。在這種通信模型下服務(wù)接口的定義要具備可擴(kuò)展性嵌施,否則在服務(wù)變更時(shí)會(huì)造成意想不到的錯(cuò)誤饲化。比如微服務(wù)的接口因?yàn)樯?jí)把之前的三個(gè)參數(shù)改成了四個(gè),上線(xiàn)后導(dǎo)致調(diào)用方大量報(bào)錯(cuò)吗伤,推薦做法服務(wù)接口的參數(shù)類(lèi)型最好是封裝類(lèi)吃靠,這樣如果增加參數(shù)就不必變更接口的簽名,而只需要在類(lèi)中添加字段就可以了足淆。
7. 避免環(huán)形依賴(lài)與雙向依賴(lài)
盡量不要有服務(wù)之間的環(huán)形依賴(lài)或雙向依賴(lài)巢块,原因是存在這種情況說(shuō)明我們的功能邊界沒(méi)有化分清楚或者有通用的功能沒(méi)有下沉下來(lái)。
8. 階段性合并
隨著你對(duì)業(yè)務(wù)領(lǐng)域理解的逐漸深入或者業(yè)務(wù)本身邏輯發(fā)生了比較大的變化巧号,亦或者之前的拆分沒(méi)有考慮的很清楚族奢,導(dǎo)致拆分后的服務(wù)邊界變得越來(lái)越混亂,這時(shí)就要重新梳理領(lǐng)域邊界丹鸿,不斷糾正拆分的合理性越走。
五、拆分的粒度把控
目前很多傳統(tǒng)的單體應(yīng)用再向微服務(wù)架構(gòu)進(jìn)行升級(jí)改造卜高,如果拆分粒度太細(xì)會(huì)增加運(yùn)維復(fù)雜度弥姻,粒度過(guò)大又起不到效果,那么改造過(guò)程中如何平衡拆分粒度呢掺涛?
弓箭原理
平衡拆分粒度可以從兩方面進(jìn)行權(quán)衡庭敦,一是業(yè)務(wù)發(fā)展的復(fù)雜度,二是團(tuán)隊(duì)規(guī)模的人數(shù)薪缆。如上圖秧廉,它就像弓箭一樣,只有當(dāng)業(yè)務(wù)復(fù)雜度和團(tuán)隊(duì)人數(shù)足夠大的時(shí)候拣帽,射出的服務(wù)拆分粒度這把劍才會(huì)飛的更遠(yuǎn)疼电,發(fā)揮出最大的威力。比如說(shuō)電商的商品服務(wù)减拭,當(dāng)我們把商品從大的單體里拆分出來(lái)的時(shí)候蔽豺,就商品服務(wù)本身來(lái)講,邏輯并沒(méi)有足夠復(fù)雜到 2~3 個(gè)人沒(méi)法維護(hù)的地步拧粪,這時(shí)我們沒(méi)有必要繼續(xù)將商品服務(wù)拆的更細(xì)修陡,但是隨著業(yè)務(wù)的發(fā)展,商品的業(yè)務(wù)邏輯變的越來(lái)越復(fù)雜可霎,可能同時(shí)服務(wù)公司的多個(gè)平臺(tái)魄鸦,此時(shí)你會(huì)發(fā)現(xiàn)商品服務(wù)本身面臨的問(wèn)題跟單體架構(gòu)階段面臨的問(wèn)題基本一樣,這個(gè)階段就需要我們將商品拆成更細(xì)粒度的服務(wù)癣朗,比如:庫(kù)存服務(wù)拾因、價(jià)格服務(wù)、類(lèi)目服務(wù)、商品基礎(chǔ)信息服務(wù)等等绢记。雖然業(yè)務(wù)復(fù)雜度已經(jīng)滿(mǎn)足了扁达,如果公司此時(shí)沒(méi)有足夠的人力(招聘不及時(shí)或員工異動(dòng)比較多),服務(wù)最好也不要拆分庭惜,拆分會(huì)因?yàn)槿肆Φ牟蛔銓?dǎo)致更多的問(wèn)題罩驻,如研發(fā)效率大幅下降(一個(gè)開(kāi)發(fā)負(fù)責(zé)與其不匹配數(shù)量的服務(wù))。這里引申另外一個(gè)問(wèn)題护赊,一個(gè)微服務(wù)究竟需要幾個(gè)開(kāi)發(fā)維護(hù)是比較理性的惠遏?
三個(gè)火槍手原則
為什么說(shuō)是三個(gè)人分配一個(gè)服務(wù)是比較理性的?而不是 4 個(gè)骏啰,也不是 2 個(gè)呢节吮?首先,從系統(tǒng)規(guī)模來(lái)講判耕,3 個(gè)人負(fù)責(zé)開(kāi)發(fā)一個(gè)系統(tǒng)透绩,系統(tǒng)的復(fù)雜度剛好達(dá)到每個(gè)人都能全面理解整個(gè)系統(tǒng),又能夠進(jìn)行分工的粒度壁熄;如果是 2 個(gè)人開(kāi)發(fā)一個(gè)系統(tǒng)帚豪,系統(tǒng)的復(fù)雜度不夠,開(kāi)發(fā)人員可能覺(jué)得無(wú)法體現(xiàn)自己的技術(shù)實(shí)力草丧;如果是 4 個(gè)甚至更多人開(kāi)發(fā)一個(gè)系統(tǒng)狸臣,系統(tǒng)復(fù)雜度又會(huì)無(wú)法讓開(kāi)發(fā)人員對(duì)系統(tǒng)的細(xì)節(jié)都了解很深。其次昌执,從團(tuán)隊(duì)管理來(lái)說(shuō)烛亦,3 個(gè)人可以形成一個(gè)穩(wěn)定的備份,即使 1 個(gè)人休假或者調(diào)配到其他系統(tǒng)懂拾,剩余 2 個(gè)人還可以支撐煤禽;如果是 2 個(gè)人,抽調(diào) 1 個(gè)后剩余的 1 個(gè)人壓力很大岖赋;如果是 1 個(gè)人檬果,這就是單點(diǎn)了,團(tuán)隊(duì)沒(méi)有備份唐断,某些情況下是很危險(xiǎn)的汁汗,假如這個(gè)人休假了,系統(tǒng)出問(wèn)題了怎么辦栗涂?最后,從技術(shù)提升的角度來(lái)講祈争,3 個(gè)人的技術(shù)小組既能夠形成有效的討論斤程,又能夠快速達(dá)成一致意見(jiàn);如果是 2 個(gè)人,可能會(huì)出現(xiàn)互相堅(jiān)持自己的意見(jiàn)忿墅,或者 2 個(gè)人經(jīng)驗(yàn)都不足導(dǎo)致設(shè)計(jì)缺陷扁藕;如果是 1 個(gè)人,由于沒(méi)有人跟他進(jìn)行技術(shù)討論疚脐,很可能陷入思維盲區(qū)導(dǎo)致重大問(wèn)題亿柑;如果是 4 個(gè)人或者更多,可能有的參與的人員并沒(méi)有認(rèn)真參與棍弄,只是完成任務(wù)而已望薄。“三個(gè)火槍手”的原則主要應(yīng)用于微服務(wù)設(shè)計(jì)和開(kāi)發(fā)階段呼畸,如果微服務(wù)經(jīng)過(guò)一段時(shí)間發(fā)展后已經(jīng)比較穩(wěn)定痕支,處于維護(hù)期了,無(wú)須太多的開(kāi)發(fā)蛮原,那么平均 1 個(gè)人維護(hù) 1 個(gè)微服務(wù)甚至幾個(gè)微服務(wù)都可以卧须。當(dāng)然考慮到人員備份問(wèn)題,每個(gè)微服務(wù)最好都安排 2 個(gè)人維護(hù)儒陨,每個(gè)人都可以維護(hù)多個(gè)微服務(wù)花嘶。
**綜上所訴,拆分粒度不是越細(xì)越好蹦漠,粒度需要符合弓箭原理及三個(gè)火槍手原則椭员。**
六、微服務(wù)拆分策略
拆分策略可以按功能和非功能維度進(jìn)行考慮津辩,功能維度主要是:劃分清楚業(yè)務(wù)的邊界拆撼,非功能維度主要考慮六點(diǎn)包括:擴(kuò)展性、復(fù)用性喘沿、高性能闸度、高可用、安全性蚜印、異構(gòu)性莺禁。接下來(lái)詳細(xì)介紹下。
1.功能維度
功能維度主要是劃分清楚業(yè)務(wù)邊界窄赋,采用的主要設(shè)計(jì)方法可以利用 DDD(即領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)哟冬,關(guān)于 DDD 的理論知識(shí)可以參考網(wǎng)上其它資料),DDD 的戰(zhàn)略設(shè)計(jì)會(huì)建立領(lǐng)域模型忆绰,可以通過(guò)領(lǐng)域模型指導(dǎo)微服務(wù)的拆分浩峡,主要分四步進(jìn)行:
- 第一步,找出領(lǐng)域?qū)嶓w和值對(duì)象等領(lǐng)域?qū)ο蟆?/li>
- 第二步错敢,找出聚合根翰灾,根據(jù)實(shí)體、值對(duì)象與聚合根的依賴(lài)關(guān)系,建立聚合纸淮。
- 第三步平斩,根據(jù)業(yè)務(wù)及語(yǔ)義邊界等因素,定義限界上下文咽块。
- 第四步绘面,每一個(gè)限界上下文可以拆分為一個(gè)對(duì)應(yīng)的微服務(wù),但也要考慮一些非功能因素侈沪。
以電商的場(chǎng)景為例揭璃,交易鏈路劃分的限界上下文如下圖左半部分,根據(jù)一個(gè)限界上下文可以設(shè)計(jì)一個(gè)微服務(wù)峭竣,拆解出來(lái)的微服務(wù)如下圖右側(cè)部分塘辅。
2.非功能維度
當(dāng)我們按照功能維度進(jìn)行拆分后,并不是就萬(wàn)事大吉了皆撩,大部分場(chǎng)景下扣墩,我們還需要加入其它維度進(jìn)一步拆分,才能最終解決單體架構(gòu)帶來(lái)的問(wèn)題扛吞。
擴(kuò)展性:區(qū)分系統(tǒng)中變與不變的部分呻惕,不變的部分一般是成熟的、通用的服務(wù)功能滥比,變的部分一般是改動(dòng)比較多亚脆、滿(mǎn)足業(yè)務(wù)迭代擴(kuò)展性需要的功能,我們可以將不變的部分拆分出來(lái)盲泛,作為共用的服務(wù)濒持,將變的部分獨(dú)立出來(lái)滿(mǎn)足個(gè)性化擴(kuò)展需要。同時(shí)根據(jù)二八原則寺滚,系統(tǒng)中經(jīng)常變動(dòng)的部分大約只占 20%柑营,而剩下的 80% 基本不變或極少變化,這樣的拆分也解決了發(fā)布頻率過(guò)多而影響成熟服務(wù)穩(wěn)定性的問(wèn)題村视。
復(fù)用性:不同的業(yè)務(wù)里或服務(wù)里經(jīng)常會(huì)出現(xiàn)重復(fù)的功能官套,比如每個(gè)服務(wù)都有鑒權(quán)、限流蚁孔、安全及日志監(jiān)控等功能奶赔,可以將這些通過(guò)的功能拆分出來(lái)形成獨(dú)立的服務(wù),也就是微服務(wù)里面的 API 網(wǎng)關(guān)所建設(shè)的內(nèi)容杠氢。再如站刑,對(duì)于滴滴業(yè)務(wù),有快車(chē)和順風(fēng)車(chē)業(yè)務(wù)鼻百,其中都涉及到了訂單支付的功能笛钝,那么就可以將訂單支付獨(dú)立出來(lái)质况,作為通用服務(wù)支撐好上層業(yè)務(wù)。如下圖:
- 高性能:將性能要求高或者性能壓力大的模塊拆分出來(lái)玻靡,避免性能壓力大的服務(wù)影響其它服務(wù)。常見(jiàn)的拆分方式和具體的性能瓶頸有關(guān)中贝,例如:電商的搶購(gòu)囤捻,性能壓力最大的是入口的排隊(duì)功能,可以將排隊(duì)功能獨(dú)立為一個(gè)服務(wù)邻寿。同時(shí)蝎土,我們也可以基于讀寫(xiě)分離來(lái)拆分,比如電商的商品信息绣否,在 App 端主要是商詳有大量的讀取操作誊涯,但是寫(xiě)入端商家中心訪問(wèn)量確很少。因此可以對(duì)流量較大或較為核心的服務(wù)做讀寫(xiě)分離蒜撮,拆分為兩個(gè)服務(wù)發(fā)布暴构,一個(gè)負(fù)責(zé)讀,另外一個(gè)負(fù)責(zé)寫(xiě)段磨。還有數(shù)據(jù)一致性是另一個(gè)基于性能維度拆分需要考慮的點(diǎn)取逾,對(duì)于強(qiáng)一致的數(shù)據(jù),屬于強(qiáng)耦合苹支,盡量放在同一個(gè)服務(wù)中(但是有時(shí)會(huì)因?yàn)楦鞣N原因需要進(jìn)行拆分砾隅,那就需要有響應(yīng)的機(jī)制進(jìn)行保證),弱一致性通痴郏可以拆分為不同的服務(wù)晴埂。
高可用:將可靠性要求高的核心服務(wù)和可靠性要求低的非核心服務(wù)拆分開(kāi)來(lái),然后重點(diǎn)保證核心服務(wù)的高可用寻定。具體拆分的時(shí)候儒洛,核心服務(wù)可以是一個(gè)也可以是多個(gè),只要最終的服務(wù)數(shù)量滿(mǎn)足“三個(gè)火槍手”的原則就可以特姐。比如:針對(duì)商家服務(wù)晶丘,可以拆分一個(gè)核心服務(wù)一個(gè)非核心服務(wù),核心服務(wù)供交易服務(wù)訪問(wèn)唐含,非核心提供給商家中心訪問(wèn)浅浮。
安全性:不同的服務(wù)可能對(duì)信息安全有不同的要求,因此把需要高度安全的服務(wù)拆分出來(lái)捷枯,進(jìn)行區(qū)別部署滚秩,比如:設(shè)置特定的 DMZ 區(qū)域?qū)Ψ?wù)進(jìn)行分區(qū)部署,可以更有針對(duì)性地滿(mǎn)足信息安全的要求淮捆,也可以降低對(duì)防火墻等安全設(shè)備吞吐量郁油、并發(fā)性等方面的要求本股,降低成本,提高效率桐腌。
異構(gòu)性:對(duì)于對(duì)開(kāi)發(fā)語(yǔ)言種類(lèi)有要求的業(yè)務(wù)場(chǎng)景拄显,可以用不同的語(yǔ)言將其功能獨(dú)立出來(lái)實(shí)現(xiàn)一個(gè)獨(dú)立服務(wù)。
以上幾種拆分方式不是多選一案站,而是可以根據(jù)實(shí)際情況自由排列組合躬审。
同時(shí)拆分不僅僅是架構(gòu)上的調(diào)整,也意味著要在組織結(jié)構(gòu)上做出相應(yīng)的適應(yīng)性?xún)?yōu)化蟆盐,以確保拆分后的服務(wù)由相對(duì)獨(dú)立的團(tuán)隊(duì)負(fù)責(zé)維護(hù)承边。
七、微服務(wù)合并
古希臘哲學(xué)家赫拉克利特曾經(jīng)說(shuō)過(guò):“人不能兩次踏進(jìn)同一條河流石挂〔┲”隨著時(shí)間的流逝,任何事物的狀態(tài)都會(huì)發(fā)生變化痹愚。線(xiàn)上系統(tǒng)同樣如此富岳,即使一個(gè)系統(tǒng)在不同時(shí)刻的狀況也絕不會(huì)一模一樣。現(xiàn)在拆分出來(lái)的服務(wù)粒度也許合適里伯,但誰(shuí)能保證這個(gè)粒度能夠一直正確呢城瞎。
八、拆分過(guò)程中要注意事項(xiàng)
1.不打無(wú)準(zhǔn)備之仗
開(kāi)發(fā)團(tuán)隊(duì)是否具備足夠的經(jīng)驗(yàn)戏锹,能否駕馭微服務(wù)的技術(shù)棧冠胯,可能是第一個(gè)需要考慮的點(diǎn)。這里并不是要求團(tuán)隊(duì)必須具備完善的經(jīng)驗(yàn)才能啟動(dòng)服務(wù)拆分锦针,如果團(tuán)隊(duì)中有這方面的專(zhuān)家固然是最好的荠察。如果沒(méi)有,那可能就需要事先進(jìn)行充分的技術(shù)論證和預(yù)演奈搜,至少不打無(wú)準(zhǔn)備之仗悉盆。避免哪個(gè)簡(jiǎn)單就先拆哪個(gè),哪個(gè)新業(yè)務(wù)要上了馋吗,先起一個(gè)服務(wù)再說(shuō)焕盟。否則可能在一些分布式常見(jiàn)的問(wèn)題上會(huì)踩坑,比如服務(wù)器資源不夠宏粤、運(yùn)維困難脚翘、服務(wù)之間調(diào)用混亂、調(diào)用重試绍哎、超時(shí)機(jī)制来农、分布式事務(wù)等等。
2.** 不斷糾正**
我們需要承認(rèn)我們的認(rèn)知是有限的崇堰,只能基于目前的業(yè)務(wù)狀態(tài)和有限的對(duì)未來(lái)的預(yù)測(cè)來(lái)制定出一個(gè)相對(duì)合適的拆分方案
沃于,而不是所謂的最優(yōu)方案,任何方案都只能保證在當(dāng)下提供了相對(duì)合適的粒度和劃分原則海诲,要時(shí)刻做好在未來(lái)的末一個(gè)時(shí)刻會(huì)變得不和時(shí)宜繁莹、需要再次調(diào)整的準(zhǔn)備。因此隨著業(yè)務(wù)的演進(jìn)饿肺,需要我們重新審視服務(wù)的劃分是否合理蒋困,如服務(wù)拆的太細(xì),導(dǎo)致人員效率反而下降敬辣,故障的概率也大大增加雪标,則需要重新劃分好領(lǐng)域邊界零院。
3.要做行動(dòng)派,而不是理論派
在具體怎么拆分上村刨,也不要太糾結(jié)于是否合適告抄,不動(dòng)手怎么知道合不合適呢?如果拆了之后發(fā)現(xiàn)真的不合適嵌牺,在重新調(diào)整就好了打洼。你可能會(huì)說(shuō),重新調(diào)整成本比較高逆粹。但實(shí)際上這個(gè)問(wèn)題的本質(zhì)是有沒(méi)有針對(duì)服務(wù)化架構(gòu)搭建起一套完成的能力體系募疮,比如服務(wù)治理平臺(tái)、數(shù)據(jù)遷移工具僻弹、數(shù)據(jù)雙寫(xiě)等等阿浓,如果有的話(huà),重新調(diào)整的成本是不會(huì)太高的蹋绽。
2021年6月11日整理于去往大連的動(dòng)車(chē)上芭毙,前方到站:盤(pán)錦。