面試官:你在項(xiàng)目的微服務(wù)拆分上,有什么心得嗎?
有幾年工作經(jīng)驗(yàn)的候選人,在簡(jiǎn)歷上大概率會(huì)寫上一些微服務(wù)相關(guān)的內(nèi)容,如:微服務(wù)拆分、微服務(wù)設(shè)計(jì)、微服務(wù)架構(gòu)方案等。
面試官如果看到這里,經(jīng)常會(huì)問這樣的一個(gè)面試問題:你在微服務(wù)拆分這件事情上有哪些心得,可以講一講嗎?
此時(shí),如果候選人沒有提前思考儲(chǔ)備這個(gè)問題,往往會(huì)被問得語無倫次,毫無章法地瞎答一氣。
我見過最離譜的答案是,候選人說他微服務(wù)拆分的心得是——微服務(wù)拆得越細(xì)越好,必須突出一個(gè)“微”字。
不要怕,學(xué)長(zhǎng)都已經(jīng)梳理好了,接下來我們就來看看,微服務(wù)拆分有哪些心得和經(jīng)驗(yàn)之談。
圖片
拆分方案
上圖中列舉的這四種拆分方案,其中并沒有優(yōu)劣好壞之分,每種拆分方案都有其適用的業(yè)務(wù)場(chǎng)景。
1、基于業(yè)務(wù)領(lǐng)域
這是一種最為常見的拆分方案,我們以電商場(chǎng)景進(jìn)行舉例,可以將一個(gè)大單體架構(gòu)的電商系統(tǒng),拆分為包含API網(wǎng)關(guān)、用戶服務(wù)、商家服務(wù)、客服服務(wù)、商品服務(wù)、訂單服務(wù)、物流服務(wù)、促銷服務(wù)和結(jié)算服務(wù)的微服務(wù)架構(gòu)的電商系統(tǒng)。
如下圖所示,拆分前:
圖片
拆分后:
圖片
2、基于變化頻率
小到系統(tǒng)代碼中的類和方法,大到系統(tǒng)的模塊或服務(wù),我們都可以將系統(tǒng)中經(jīng)常變化的部分和變化頻率很低的部分進(jìn)行分離。
分離變與不變的意義是,研發(fā)人員可以在整個(gè)DevOps周期中,更加聚焦地關(guān)注經(jīng)常變化的服務(wù)的可維護(hù)性、可擴(kuò)展性,最終起到提升研發(fā)效率的效果。
此外,我們可以把經(jīng)常變化的服務(wù)的粒度拆分得細(xì)一些,因?yàn)樗鼤?huì)隨著日常需求的不斷迭代而逐步變大,避免以后進(jìn)行二次拆分。反之,變化頻率很低的穩(wěn)定態(tài)服務(wù)的粒度拆分得粗一些,減少分布式系統(tǒng)的鏈路復(fù)雜度和運(yùn)維困難度。
3、基于重要等級(jí)
這種拆分方案的做法是,將重要等級(jí)高的業(yè)務(wù)模塊與重要等級(jí)較低的業(yè)務(wù)模塊進(jìn)行拆分,使其形成各自的服務(wù),旨在通過鏈路隔離的方式減少后者對(duì)于前者的影響,提升系統(tǒng)核心鏈路的可用性。
當(dāng)然,除了應(yīng)用服務(wù)器之外,兩者在中間件和數(shù)據(jù)庫(kù)服務(wù)器上也要各用各的,這樣才能起到徹底隔離的效果。
我們還是以電商場(chǎng)景進(jìn)行舉例,如下圖所示:
圖片
另外,基于重要等級(jí)進(jìn)行系統(tǒng)拆分,是一項(xiàng)極其耗時(shí)且復(fù)雜的工作,研發(fā)團(tuán)隊(duì)在考慮此策略時(shí),一定要衡量好ROI(投入產(chǎn)出比)。
個(gè)人建議,如果是一天都沒多少業(yè)務(wù)量的創(chuàng)新業(yè)務(wù)或邊緣業(yè)務(wù),那就免了吧。
4、基于并發(fā)度
這種拆分方式,是將系統(tǒng)中并發(fā)度明顯很高的業(yè)務(wù)模塊單獨(dú)拆分出來,旨在以專人專事專用服務(wù)的方式更好地解決問題。
舉個(gè)例子,IPhone單品秒殺和正常業(yè)務(wù)場(chǎng)景下的訂單服務(wù),由于其并發(fā)度不同,在架構(gòu)方案、存儲(chǔ)設(shè)計(jì)和硬件資源配置上,思路也是完全不一樣的。那么,將兩者進(jìn)行微服務(wù)拆分,可以使其更加聚焦地解決各自業(yè)務(wù)場(chǎng)景的問題。
再舉一個(gè)在線教育約課場(chǎng)景的例子,公司存在這樣的一個(gè)業(yè)務(wù)場(chǎng)景,每周五中午12點(diǎn)開放預(yù)約下周的課程。那么,系統(tǒng)百萬用戶中的大部分人都去搶著預(yù)約心儀老師的課程。
此時(shí),約課系統(tǒng)需要承擔(dān)的請(qǐng)求壓力極大,尤其是最為核心的“預(yù)約課程”接口,每周五中午12點(diǎn)到12點(diǎn)10分期間的TPS甚至可以達(dá)到萬級(jí)別。
因此,在我們進(jìn)行系統(tǒng)改造優(yōu)化之前,在 “每周五中午12點(diǎn)到12點(diǎn)10分” 這個(gè)時(shí)間段內(nèi),經(jīng)常會(huì)出現(xiàn)系統(tǒng)扛不住請(qǐng)求流量而導(dǎo)致宕機(jī)的情況出現(xiàn)。
在這種瞬時(shí)流量洪峰的情況下,可以通過MQ消峰的方式解決。我們需要做的是將“約課前置服務(wù)”從“約課服務(wù)”中拆分出來,把用戶的約課請(qǐng)求中的參數(shù)進(jìn)行前置校驗(yàn)后,將請(qǐng)求信息發(fā)送給Kafka Broker。
如下圖所示:
圖片
拆分粒度
對(duì)于微服務(wù)的理解,Martin Fowler曾經(jīng)說過這樣一段話:
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.
有些同學(xué)看到了small services這兩個(gè)單詞,就認(rèn)為微服務(wù)的拆分粒度越小越好,其實(shí)并不是這樣的。
粒度過小的微服務(wù)不僅會(huì)增加硬件成本,同時(shí)也會(huì)過度消耗團(tuán)隊(duì)的DevOps成本,在這里大家不妨了解一下三個(gè)火槍手原則。
三個(gè)火槍手原則意思是,一個(gè)微服務(wù)拆分的粒度,最好可以容納三個(gè)工程師同時(shí)對(duì)其進(jìn)行開發(fā)。
從團(tuán)隊(duì)的角度上,三個(gè)工程師可以形成很好的互備;從系統(tǒng)的角度上,三個(gè)工程師開發(fā)維護(hù)的系統(tǒng),復(fù)雜度不會(huì)太高,也很難由于代碼沖突而導(dǎo)致互相影響。因此,三個(gè)火槍手原則算是從多個(gè)角度平衡后的最優(yōu)解吧。
當(dāng)然,這里面說的“三個(gè)”工程師只是一個(gè)參考意見,并不是完全一成不變的,可根據(jù)公司研發(fā)團(tuán)隊(duì)的實(shí)際情況進(jìn)行上下浮動(dòng)。
拆分標(biāo)準(zhǔn)
再列舉幾個(gè)微服務(wù)拆分的標(biāo)準(zhǔn)吧,這個(gè)并不需要完全對(duì)標(biāo),只需要盡量往這個(gè)方向上靠即可。
1、單一職責(zé)原則
以上文中的電商場(chǎng)景進(jìn)行微服務(wù)拆分為例,每個(gè)微服務(wù)盡量做到只負(fù)責(zé)一個(gè)業(yè)務(wù)領(lǐng)域,這樣可以使其職責(zé)更加清晰。
2、服務(wù)自治原則
每個(gè)微服務(wù)都需要做到高度自治,可以進(jìn)行獨(dú)立開發(fā)、獨(dú)立測(cè)試、獨(dú)立部署和獨(dú)立運(yùn)行,盡量減少對(duì)其他服務(wù)的強(qiáng)依賴,這樣能夠降低團(tuán)隊(duì)間的溝通成本。
3、可觀察性原則
每個(gè)微服務(wù)都可以通過監(jiān)控系統(tǒng)、日志系統(tǒng)和鏈路追蹤系統(tǒng)觀察到其運(yùn)行狀態(tài)、性能指標(biāo)和業(yè)務(wù)處理情況。
4、可復(fù)用性原則
每個(gè)微服務(wù)都應(yīng)該對(duì)外提供通用的能力,可以為其他的多個(gè)服務(wù)復(fù)用,這樣可以提升研發(fā)效率。