專欄上一期,我談了實施微服務需要避免踩的陷阱,簡單提煉為:
微服務拆分過細,過分強調(diào)“small”。
微服務基礎設施不健全,忽略了“automated”。
微服務并不輕量級,規(guī)模大了后,“l(fā)ightweight”不再適應。
針對這些問題,今天我們看看微服務最佳實踐應該如何去做。我會分兩期介紹這部分內(nèi)容,今天是微服務架構最佳實踐的方法篇,下一期是基礎設施篇。
服務粒度
針對微服務拆分過細導致的問題,我建議基于團隊規(guī)模進行拆分,類似貝索斯在定義團隊規(guī)模時提出的“兩個披薩”理論(每個團隊的人數(shù)不能多到兩張披薩都不夠吃的地步),分享一個我認為微服務拆分粒度的“三個火槍手”原則,即一個微服務三個人負責開發(fā)。當我們在實施微服務架構時,根據(jù)團隊規(guī)模來劃分微服務數(shù)量,如果業(yè)務規(guī)繼續(xù)發(fā)展,團隊規(guī)模擴大,我們再將已有的微服務進行拆分。例如,團隊最初有 6 個人,那么可以劃分為 2 個微服務,隨著業(yè)務的發(fā)展,業(yè)務功能越來越多,邏輯越來越復雜,團隊擴展到 12 個人,那么我們可以將已有的 2 個微服務進行拆分,變成 4 個微服務。
為什么是 3 個人,不是 4 個,也不是 2 個呢?
首先,從系統(tǒng)規(guī)模來講,3 個人負責開發(fā)一個系統(tǒng),系統(tǒng)的復雜度剛好達到每個人都能全面理解整個系統(tǒng),又能夠進行分工的粒度;如果是 2 個人開發(fā)一個系統(tǒng),系統(tǒng)的復雜度不夠,開發(fā)人員可能覺得無法體現(xiàn)自己的技術實力;如果是 4 個甚至更多人開發(fā)一個系統(tǒng),系統(tǒng)復雜度又會無法讓開發(fā)人員對系統(tǒng)的細節(jié)都了解很深。
其次,從團隊管理來說,3 個人可以形成一個穩(wěn)定的備份,即使 1 個人休假或者調(diào)配到其他系統(tǒng),剩余 2 個人還可以支撐;如果是 2 個人,抽調(diào) 1 個后剩余的 1 個人壓力很大;如果是 1 個人,這就是單點了,團隊沒有備份,某些情況下是很危險的,假如這個人休假了,系統(tǒng)出問題了怎么辦?
最后,從技術提升的角度來講,3 個人的技術小組既能夠形成有效的討論,又能夠快速達成一致意見;如果是 2 個人,可能會出現(xiàn)互相堅持自己的意見,或者 2 個人經(jīng)驗都不足導致設計缺陷;如果是 1 個人,由于沒有人跟他進行技術討論,很可能陷入思維盲區(qū)導致重大問題;如果是 4 個人或者更多,可能有的參與的人員并沒有認真參與,只是完成任務而已。
“三個火槍手”的原則主要應用于微服務設計和開發(fā)階段,如果微服務經(jīng)過一段時間發(fā)展后已經(jīng)比較穩(wěn)定,處于維護期了,無須太多的開發(fā),那么平均 1 個人維護 1 個微服務甚至幾個微服務都可以。當然考慮到人員備份問題,每個微服務最好都安排 2 個人維護,每個人都可以維護多個微服務。
拆分方法
基于“三個火槍手”的理論,我們可以計算出拆分后合適的服務數(shù)量,但具體怎么拆也是有技巧的,并不是快刀砍亂麻隨便拆分成指定數(shù)量的微服務就可以了,也不是只能按照業(yè)務來進行拆分,而是可以根據(jù)目的的不同靈活地選取不同的拆分方式。接下來我一一介紹常見的拆分方式。
1. 基于業(yè)務邏輯拆分
這是最常見的一種拆分方式,將系統(tǒng)中的業(yè)務模塊按照職責范圍識別出來,每個單獨的業(yè)務模塊拆分為一個獨立的服務。
基于業(yè)務邏輯拆分雖然看起來很直觀,但在實踐過程中最常見的一個問題就是團隊成員對于“職責范圍”的理解差異很大,經(jīng)常會出現(xiàn)爭論,難以達成一致意見。例如:假設我們做一個電商系統(tǒng),第一種方式是將服務劃分為“商品”“交易”“用戶”3 個服務,第二種方式是劃分為“商品”“訂單”“支付”“發(fā)貨”“買家”“賣家”6 個服務,哪種方式更合理,是不是劃分越細越正確?
導致這種困惑的主要根因在于從業(yè)務的角度來拆分的話,規(guī)模粗和規(guī)模細都沒有問題,因為拆分基礎都是業(yè)務邏輯,要判斷拆分粒度,不能從業(yè)務邏輯角度,而要根據(jù)前面介紹的“三個火槍手”的原則,計算一下大概的服務數(shù)量范圍,然后再確定合適的“職責范圍”,否則就可能出現(xiàn)劃分過粗或者過細的情況,而且大部分情況下會出現(xiàn)過細的情況。
例如:如果團隊規(guī)模是 10 個人支撐業(yè)務,按照“三個火槍手”規(guī)則計算,大約需要劃分為 4 個服務,那么“登錄、注冊、用戶信息管理”都可以劃到“用戶服務”職責范圍內(nèi);如果團隊規(guī)模是 100 人支撐業(yè)務,服務數(shù)量可以達到 40 個,那么“用戶登錄“就是一個服務了;如果團隊規(guī)模達到 1000 人支撐業(yè)務,那“用戶連接管理”可能就是一個獨立的服務了。
2. 基于可擴展拆分
將系統(tǒng)中的業(yè)務模塊按照穩(wěn)定性排序,將已經(jīng)成熟和改動不大的服務拆分為穩(wěn)定服務,將經(jīng)常變化和迭代的服務拆分為變動服務。穩(wěn)定的服務粒度可以粗一些,即使邏輯上沒有強關聯(lián)的服務,也可以放在同一個子系統(tǒng)中,例如將“日志服務”和“升級服務”放在同一個子系統(tǒng)中;不穩(wěn)定的服務粒度可以細一些,但也不要太細,始終記住要控制服務的總數(shù)量。
這樣拆分主要是為了提升項目快速迭代的效率,避免在開發(fā)的時候,不小心影響了已有的成熟功能導致線上問題。
3. 基于可靠性拆分
將系統(tǒng)中的業(yè)務模塊按照優(yōu)先級排序,將可靠性要求高的核心服務和可靠性要求低的非核心服務拆分開來,然后重點保證核心服務的高可用。具體拆分的時候,核心服務可以是一個也可以是多個,只要最終的服務數(shù)量滿足“三個火槍手”的原則就可以。
這樣拆分帶來下面幾個好處:
避免非核心服務故障影響核心服務
例如,日志上報一般都屬于非核心服務,但是在某些場景下可能有大量的日志上報,如果系統(tǒng)沒有拆分,那么日志上報可能導致核心服務故障;拆分后即使日志上報有問題,也不會影響核心服務。
核心服務高可用方案可以更簡單
核心服務的功能邏輯更加簡單,存儲的數(shù)據(jù)可能更少,用到的組件也會更少,設計高可用方案大部分情況下要比不拆分簡單很多。
能夠降低高可用成本
將核心服務拆分出來后,核心服務占用的機器、帶寬等資源比不拆分要少很多。因此,只針對核心服務做高可用方案,機器、帶寬等成本比不拆分要節(jié)省較多。
4. 基于性能拆分
基于性能拆分和基于可靠性拆分類似,將性能要求高或者性能壓力大的模塊拆分出來,避免性能壓力大的服務影響其他服務。常見的拆分方式和具體的性能瓶頸有關,可以拆分 Web 服務、數(shù)據(jù)庫、緩存等。例如電商的搶購,性能壓力最大的是入口的排隊功能,可以將排隊功能獨立為一個服務。
以上幾種拆分方式不是多選一,而是可以根據(jù)實際情況自由排列組合,例如可以基于可靠性拆分出服務 A,基于性能拆分出服務 B,基于可擴展拆分出 C/D/F 三個服務,加上原有的服務 X,最后總共拆分出 6 個服務(A/B/C/D/F/X)。
基礎設施
大部分人主要關注的是微服務的“small”和“l(fā)ightweight”特性,但實際上真正決定微服務成敗的,恰恰是那個被大部分人都忽略的“automated”。為何這樣說呢?因為服務粒度即使劃分不合理,實際落地后如果團隊遇到麻煩,自然會想到拆服務或者合服務;如果“automated”相關的基礎設施不健全,那微服務就是焦油坑,讓研發(fā)、測試、運維陷入我上一期講的各種微服務陷阱中。
微服務基礎設施如下圖所示:

看到上面這張圖,相信很多人都會倒吸一口涼氣,說好的微服務的“輕量級”呢?都這么多基礎設施還好意思說自己是“輕量級”,感覺比 ESB 還要復雜???
確實如此,微服務并不是很多人認為的那樣又簡單又輕量級。要做好微服務,這些基礎設施都是必不可少的,否則微服務就會變成一個焦油坑,讓業(yè)務和團隊在里面不斷掙扎且無法自拔。因此也可以說,微服務并沒有減少復雜度,而只是將復雜度從 ESB 轉移到了基礎設施。你可以看到,“服務發(fā)現(xiàn)”“服務路由”等其實都是 ESB 的功能,只是在微服務中剝離出來成了獨立的基礎系統(tǒng)。
雖然建設完善的微服務基礎設施是一項龐大的工程,但也不用太過灰心,認為自己團隊小或者公司規(guī)模不大就不能實施微服務了。第一個原因是已經(jīng)有開源的微服務基礎設施全家桶了,例如大名鼎鼎的 Spring Cloud 項目,涵蓋了服務發(fā)現(xiàn)、服務路由、網(wǎng)關、配置中心等功能;第二個原因是如果微服務的數(shù)量并不是很多的話,并不是每個基礎設施都是必須的。通常情況下,我建議按照下面優(yōu)先級來搭建基礎設施:
1. 服務發(fā)現(xiàn)、服務路由、服務容錯:這是最基本的微服務基礎設施。
2. 接口框架、API 網(wǎng)關:主要是為了提升開發(fā)效率,接口框架是提升內(nèi)部服務的開發(fā)效率,API 網(wǎng)關是為了提升與外部服務對接的效率。
3. 自動化部署、自動化測試、配置中心:主要是為了提升測試和運維效率。
4. 服務監(jiān)控、服務跟蹤、服務安全:主要是為了進一步提升運維效率。
以上 3 和 4 兩類基礎設施,其重要性會隨著微服務節(jié)點數(shù)量增加而越來越重要,但在微服務節(jié)點數(shù)量較少的時候,可以通過人工的方式支撐,雖然效率不高,但也基本能夠頂住。
小結
今天我為你講了微服務架構實踐中的三個關鍵點:如何把握拆分粒度、按照什么維度進行拆分、需要什么基礎設施支撐,希望對你有所幫助。
這就是今天的全部內(nèi)容,留一道思考題給你吧,參考文章中提到的方法,思考一下你所在的業(yè)務微服務架構是否還有可以改進和提升的空間?
歡迎你把答案寫到留言區(qū),和我一起討論。相信經(jīng)過深度思考的回答,也會讓你對知識的理解更加深刻。(編輯亂入:精彩的留言有機會獲得豐厚福利哦?。?/p>