七個關鍵問題的應對策略

1。如何合理拆分微服務

當一個系統服務化的時候,就會面臨一個問題:如何進行服務的劃分?怎麼確定服務的粒度?有沒有一些可以參考的業界通用規則?

實際上服務劃分的本質是對系統進行架構設計,服務的劃分粒度沒有絕對的過大或過小之說,不同階段的側重點和思考的角度也不盡相同。

微服務架構深度解析與最佳實踐 - 第四部分:如何拆分微服務和改造遺留系統

創業初期的團隊,過分的追求微服務,為了“微”而微,反而會導致業務邏輯過於分散,技術架構過於複雜,團隊基礎設施搭建能力弱,進而導致忽略了快速迭代交付產品的重要性,可能錯失了市場機會。所以,關於服務的劃分不是對錯的選擇題,而是需要綜合考慮各種外界的因素,所作出的一個最適合的決策,這些外界因素通常包括業務、技術債、開發、運維、測試這

五個方面:

業務所處領域的市場性質:對市場比較敏感的專案,創業初期粒度應該儘量劃分的粗一些,先提供充足的彈藥去佔領市場,然後再去考慮對系統進行重構和最佳化;

與原有系統之間的關係:對於歷史遺留的系統,需要做好新舊系統之間的邊界劃分,避免過於激進、過大幅度的改造,應該採取小步快跑的方式,有節奏的對老系統進行服務化改造;

開發團隊的成熟度:服務化帶來的技術風險應該提前進行評估,要考慮團隊的承受度,用合適的人做適合的事,考慮團隊需要有包括敏捷,包括 Devops,包括基礎設施,運維和測試的自動化等基礎能力;

基礎設施的搭建能力:在進行細粒度的服務劃分時,要考慮團隊是否有足夠的能力來支撐大量服務例項執行的運維複雜度,是否可以做好分散式的日誌追蹤和服務的監控;

測試團隊的測試執行效率:過於細粒度的服務劃分,如果測試團隊不能透過自動化測試、自動迴歸、壓力測試、極限測試等手段來提高測試執行效率,必然會帶來測試工作量的大幅度上升,進而影響整個專案的上線週期;

微服務架構深度解析與最佳實踐 - 第四部分:如何拆分微服務和改造遺留系統

如果沒有特別強烈的大規模水平擴充套件需求,拆分就沒有必要,反而把問題搞複雜了。進行服務化的拆分時,通常會先按照業務子系統先進行一次劃分,根據業務邏輯和資料的關係劃分為若干個子系統,然後再考慮子系統內部是否可以再次進行拆分。至於拆分的基本原則,我推薦:

高內聚低耦合:這個已經提了很多了,簡單說一下,就是要把強相關的部分,總是會一起改動的部分,聚合到一起,相關性不大的部分拆開,可以參考 DDD 中的一些辦法。

粗粒度服務:服務的粒度要稍微的抽象和粗粒度一些,因為服務是基於業務場景的抽象和設計,不能做成是直接把資料庫的增刪改查暴露出來成介面和方法,而是應該隱藏這些細節,考慮清楚從業務和客戶角度來看,哪些步驟和過程,是必須封裝起來的,細節隱藏掉,然後對外提供的就是粗粒度的服務,而在單體系統的時候,我們可以直接呼叫這些細節,無需過多考慮。

微服務架構深度解析與最佳實踐 - 第四部分:如何拆分微服務和改造遺留系統

2。遺留系統應該如何改造

對舊系統進行改造,可以分為幾個步驟:拆分前準備階段,設計拆分改造方案,實施拆分計劃。下面是我的一些經驗之談。

1)拆分之前先梳理系統關係和介面

其中準備階段主要是梳理清楚了依賴關係和介面,就可以思考如何來拆,第一刀切在哪兒裡,即能達到快速把一個複雜單體系統變成兩個更小系統的目標,又能對系統的現有業務影響最小。要儘量避免構建出一個分散式的單體應用,一個包含了一大堆互相之間緊耦合的服務,卻又必須部署在一起的所謂分散式系統。沒分析清楚就強行拆,可能就一不小心剪斷了大動脈,立馬搞出來一個 A 類大故障,後患無窮。

2)不同階段拆分要點不同,每個階段的關注點要聚焦

拆分本身可以分成三個階段,核心業務和非業務部分的拆分、核心業務的調整設計、核心業務內部的拆分。

第一階段將核心業務瘦身,把非核心的部分切開,減少需要處理的系統大小;

第二階段。重新按照微服務設計核心業務部分;

第三階段把核心業務部分重構設計落地。

拆分的方式也有三個:程式碼拆分、部署拆分、資料拆分。

程式碼直接體現了依賴關係,拆完就可以單獨打包部署。但是有時候,我們可以透過控制一些提供服務的開關,使用同一份程式碼和打包的程式,部署多組程序,每組提供不同的服務,這就是部署拆分,比如同一份程式碼,我們部署了 3 組機器,A 組 5 臺提供訂單服務,B 組 2 臺提供使用者服務,C 組 2 臺提供任務排程處理任務。資料拆分最複雜,涉及到程式碼的調整,SQL 和事務的分析和重構,資料庫表的拆分甚至資料遷移,資料結構的調整和資料遷移則一般意味著需要停機維護。這三個方式,可以在適當的條件下選擇先做哪個操作合適。

另外,每個階段需要聚焦到一兩個具體的目標,否則目標太多反而很難把一件事兒做通透。例如某個系統的微服務拆分,制定瞭如下的幾個目標:

效能指標(吞吐和延遲):核心交易吞吐提升一倍以上(TPS:1000->10000),A 業務延遲降低一半(Latency:250ms->125ms),B 業務延遲降低一半(Latency:70ms->35ms)。

穩定性指標(可用性,故障恢復時間):可用性>=99。99%,A 類故障恢復時間<=15 分鐘,季度次數<=1 次。

質量指標:編寫完善的產品需求文件、設計文件、部署運維文件,核心交易部分程式碼 90%以上單測覆蓋率和 100%的自動化測試用例和場景覆蓋,實現可持續的效能測試基準環境和長期持續效能最佳化機制。

擴充套件性指標:完成程式碼、部署、執行時和資料多個維度的合理拆分,對於核心系統重構後的各塊業務和交易模組、以及對應的各個資料儲存,都可以隨時透過增加機器資源實現伸縮擴充套件。

可維護性指標:建立全面完善的監控指標、特別是全鏈路的實時效能指標資料,覆蓋所有關鍵業務和狀態,縮短監控報警響應處置時間,配合運維團隊實現容量規劃和管理,出現問題時可以在一分鐘內拉起系統或者回滾到上一個可用版本(啟動時間<=1 分鐘)。

易用性指標,透過重構實現新的 API 介面既合理又簡單,極大的滿足各個層面使用者的使用和需要,客戶滿意度持續上升。

業務支援指標:對於新的業務需求功能開發,在保障質量的前提下,開發效率提升一倍,開發資源和週期降低一半。

核心人員指標:培養 10 名以上熟悉核心交易業務和新系統的一線技術人員,形成結構合理的核心研發人才梯隊。

結果可想而知了,目前太多了,反而沒有目標。最後第一階段只選擇了穩定性作為最重要的指標,先穩住系統,然後再在後面的階段裡選擇其他指標,逐步實現各個目標。

3)快速迭代,找到突破口,持續產出

大家都知道,敏捷開發之所以流行,就是因為小步快跑,快速迭代,實現對業務變化和新需求的第一時間響應,這對快速發展變化的外部市場,以及 KPI 壓力非常大的業務部門非常重要。研發團隊在系統改造過程也可以透過快速的階段性產出,來證明團隊的技術能力和推進水平,增進互相的背靠背信任關係,為長期的順暢合作打下堅實基礎。這方面,很多研發團隊都想試圖憋大招,搞個大專案,反而慢慢失去各個利益方的耐心,最終把合作關係搞僵,吃了大虧。

4)大膽假設,小心求證,穩步上線

凡事不破不立,拆分改造過程,我們每一次改動的地方,可能有多個不同的方案和路徑,具體選擇哪一個最合適,這需要我們放開思路,大膽假設,充分吸收各方面的意見和想法,然後小心謹慎的去測試,甚至在線上做驗證,保障萬無一失後,最後上線。

5)保障質量,不斷重構和改善現有設計和程式碼

所有的事物都有產生,發展,衰退和消亡的過程。長期來看,軟體系統的程式碼質量肯定是會一直下降的,就像是人的身體健康,到了一定的程度,就會難以為繼,需要重構或者重做。而不斷的重構,改善現有的設計集合程式碼,就像是一直在保養身體,可以減緩衰老,保證健康,增加壽命。

6)取得領導和業務方的支援,過程和決策透明化

拆分改造看起來,沒有給系統帶來明確的可見收益,比如沒有明顯改進了使用者體驗,也沒有給系統新增了一個業務功能,但是卻涉及到多方參與,付出勞動,這就必然會帶來很大的阻力,怎麼辦呢?

還是從《管理的常識》一書裡,我看到了一個很有道理的話:”如果無法推動問題背後的人解決問題,那說明對問題挖掘的還不夠深“。現代化的工作教會我們,雙贏/多贏是協作的唯一辦法,也是可以持續的辦法。

搞清楚怎麼才能推動各個合作方的支援,怎麼才能讓領導同意,如果我們現在提的意見,他們不同意,那麼他們關心的點是什麼,怎麼把他們關心的點,納入到這個工作範圍裡來,從而實現大家可以達成一致來合作。同時需要注意的是,資訊一定要透明,決策要公開,讓大家都直接參與到這個過程,從而明確目標,一致前行。

總結成 48 字箴言的“微服務拆分核心價值觀”:

功能剝離、資料解耦

自然演進、逐步拆分

小步快跑、快速迭代

灰度釋出、謹慎試錯

提質量線、還技術債

各方一致,過程透明

理想中的系統拆分改造效果(實際上一般最後都雞飛狗跳):

微服務架構深度解析與最佳實踐 - 第四部分:如何拆分微服務和改造遺留系統