服務拆分的設計和思考(B2B 技術共享第九篇)

本文主要想給你們分享一下,宋小菜這三年來,是如何從單點巨石系統演變成領域驅動的服務化設計的。這個演變如今還在繼續,咱們在實踐過程當中遇到了不少坑,也收穫了經驗和思考。前端

1、早期的系統

1.1 惟快不破

我是在宋小菜處於籌備階段就加入的第一個程序員,見證了宋小菜系統從0到1的全過程。那時候的技術團隊只有一個產品經理,一個程序員(就是我),還有五個外包同窗。在宋小菜第一天工做的日子我還記得很是清楚,是2015年1月18日,咱們的第一個任務我也記得很是清楚,在3月份前產出一個能夠交易的平臺。交易須要什麼,用戶、帳戶、商品、資金、訂單……這些模塊組成了宋小菜最先的交易系統。那時候爲了快,犧牲了太多的東西,好比缺少了總體的架構設計、缺少了充足的業務理解、缺少了功能的抽象、缺少了性能的分析。這些行爲在如今看起來,很是難以想象也不可接受。我時常在想一個問題,若是以咱們如今的經驗和理解,穿越回到三年前去開發最先期的宋小菜系統,又會是一番怎麼樣的場景呢?我會一開始就規劃出用戶中心、商品中心等幾大中心嗎?我會一開始就設計無狀態系統和水平擴展能力嗎?我會一開始就開發網關平臺收攏和規範全部API的調用嗎?答案必定是不會的,並且這樣作結果每每也不必定會比當初更好。 早期系統並不須要一些相似核武器同樣的架構設計和中間件,真正須要的是最快速度爲公司的業務提供戰鬥的能力。程序員

1.2 面臨的問題

那時候主要的系統有兩個,分別爲內部的ERP系統和供客戶端調用的API服務系統,這兩個系統完成了咱們的交易的閉環。隨後的兩年時間裏,瘋狂的業務代碼堆積和不受控制的重複代碼,使得這個系統愈來愈笨重。那時候的系統結構很是簡單,公共的模塊以jar包的形式抽離出來,其中ERP系統的依賴關係能夠參見下圖:服務器

image1.png | center | 1338x1274

這時候的系統改造就變得很是痛苦,每次發佈都會變得異常緊張,生怕有哪一個模塊的jar包改動了沒有更新,就致使系統沒法順利啓動。曾經有那麼一段時間,我會很害怕系統的發佈,若是順利發佈,我也會長舒一口氣。
複製代碼
再發展下去,就已經不是懼怕系統發佈這麼簡單了,系統逐漸進入一個可怕的死循環了:
在系統的各個地方散落了一些異常刺眼的註釋,好比「這段代碼太牛逼了,我不敢改,因此就複製了一份」、「這部分的邏輯是xxx寫的,不要輕易改動」等等。如下六點是咱們系統存在的主要問題:
複製代碼
  1. jar包管理混亂,常常致使系統沒法構建;
  2. 笨拙、耦合嚴重,發佈影響點混亂,底層jar的變動,致使每一個應用系統都須要發佈;
  3. 開發過程當中協做困難;
  4. 新人很難上手,理解困難;
  5. 不容易管理,出現不少不潔代碼;
  6. 技術債務越背越多; 當公司規模還小的時候,業務複雜度和系統複雜度都還處於一個比較好接受的階段,巨石系統每每是一個比較高效的架構設計。可是隨着業務的不斷擴展,複雜度和訪問量進一步的增長,若是突破了某一個臨界點了,系統架構的升級和服務的拆分,就變成不得不作的一件事了。

2、服務拆分上遇到的坑

2.1 缺少規劃

當時決定進行服務拆分的時候,技術團隊的規模也並非特別龐大,也並無哪位同窗對於服務的拆分有較多經驗。如今回想起來,那時候的起步確實草率了點。咱們沒有作太多的規劃,直接到了「說幹就幹」的環節了。可想而知服務會出現的多麼凌亂,一會一個「價格中心」,一會一個「權限中心」,哪一個簡單就先拆哪一個,哪一個新業務要上了,先起一個服務再說。隨後就暴露出了服務器資源不夠、運維困難、服務之間調用混亂等問題。 你們意識到這個問題的時候,還不算病入膏肓。咱們馬上進行了宋小菜總體服務大盤的設計和劃分,將服務分爲上下兩層。上層爲業務層,下層爲能力層,儘可能使得服務之間的調用變成樹狀,而不是環狀。架構

image3.png | center | 2198x1154

2.2 服務的粒度

服務的拆分是一件很是容易的事情,關鍵在於粒度的把控。那時候對於微服務有一種近乎偏執的理解,認爲只要某個功能模塊獨立,就得變成一個服務獨立出來,並且爲了保證可用性還必須起兩個節點。按照這個理論咱們進行了實踐,也確實出現了很多極端的操做。逐漸咱們明白這個思路是有一些問題的,而要解決這個問題,咱們必須對於服務拆分的理念達成統一。 咱們嘗試使用DDD(領域驅動設計)來進行服務的規劃,基於DDD的設計方法,從當前業務出發,抽象業務找到宋小菜業務的核心能力,並以此做爲服務進行拆分。但DDD是方法論,並非教條和金科玉律,在使用的過程當中也千萬不要走火入魔。 使用了DDD進行分析以後,咱們發現了一個更加頭疼的問題,那就是之前的服務拆的太細了,把不少不應拆分出去的服務拆成了兩個甚至更多。因此以後咱們內部啓動了「方舟項目」,該項的目的主要有這些:運維

  1. 對於服務如何拆分,在團隊中構建共同的認知,並推動使用DDD;
  2. 定義微服務工程結構和規範;
  3. 將以往粒度過細的服務進行合併; 經過此次趟坑,咱們也明白服務的拆分是一件很是慎重的事情,拆分一時爽,要是再想合併和統一,就不是那麼容易的一件事情了。

2.3 可能出現的風險

2.3.1 經驗

開發團隊是否具有足夠的經驗,可否駕馭微服務的技術棧,多是第一個須要考慮的點。這裏並非要求團隊必須具有完善的經驗才能啓動服務拆分,若是團隊中有這方面的專家當然是最好的。若是沒有,那可能就須要事先進行充分的技術論證和預演,至少不打無準備之仗。 上文也提到了,咱們的啓動略微草率了一些,團隊中也並無這方面很是專業的同窗坐鎮,因此在一些分佈式常見的問題上,都踩了坑,好比調用重試、超時機制、分佈式事務等,這些問題一出現,不少沒有經驗的同窗會很是抓狂,甚至無從下手。分佈式

2.3.2 穩定的測試

服務的拆分,必然會出現的問題就是加大了同窗們的開發自測難度。之前的系統不管是在本地啓動,或是發佈在測試環境,全部的調用都是肯定性的。可是一旦某一塊服務拆分出來了,可能會面臨不少問題:微服務

  1. 本地針對遠程服務的調用,多是被禁止的,那就須要使用mock的方式來解決了,在本機單元測試的時候,主要測試的是業務邏輯和流程,並不能很完美的測到遠程調用的返回數據。
  2. 調用的測試環境可能很不穩定,當你想要調用的時候,服務可能早就掛了。
  3. 多個項目組開發新功能的時候,調用了同一個服務,這時候有可能會由於服務器資源有限,致使你們資源競爭。 不一樣公司狀況不一樣,爲開發同窗營造的測試環境也不盡相同。但有一點是必定的,若是測試複雜,會給開發同窗形成很大的壓力。明明一個很簡單的功能,改一改可能只須要5分鐘,可是想走完一次完整的測試,卻花了他1個小時的時間。若是在服務化拆分後不能很好的解決,會致使開發同窗有愈來愈多的僥倖心理和偷懶的狀況,不進行測試就提交了代碼或進行了發佈。

2.3.3 日誌

服務的拆分必然會致使日誌散落在各地,不管是定位問題須要查看日誌,仍是一些事件須要基於日誌去實現,都會變得比以往復雜不少。一開始的時候,咱們並無意識到這個問題,因此不少開發同窗出現bug或是故障以後,不知道如何去定位了。由於一個方法的調用,可能會由於服務化的調用被放大幾回甚至十幾回,最後的錯誤到底出如今哪裏,如何去找去看,都是一個問題。post

3、結束語

服務拆分可能出現的問題還有不少,在這裏也只是將一些最容易出現的場景分享給你們。但願經過本文,能夠給那些準備進行服務拆分,或在正處於服務拆分起步階段的團隊一些建議和經驗。

關於如何搭建高效率的生鮮B2B平臺,由於包含的內容較多,也很複雜,沒法再一篇文章中給你們講清楚,本篇文章只是拋磚引玉,下面將分爲多篇文章從行業現狀、業務現狀、產品概述、技術團隊搭建、服務端技術平臺搭建、前端開發等多個維度來說述,咱們將三年多在B2B領域沉澱的核心產品和技術平臺公開,但願更多行業的人能深刻了解,少走一些彎路,但願對你們有幫助,本系列文章分佈以下(會繼續更新):性能

一、《如何搭建高效率的生鮮 B2B 平臺(B2B 技術共享第一篇)》單元測試

二、《宋小菜如何切入生鮮 B2B 市場(B2B 技術共享第二篇)》

三、《生鮮 B2B 平臺的產品體系如何迭代(B2B 技術共享第三篇)》

四、《生鮮 B2B 如何搭建高效的技術團隊(B2B 技術共享第四篇)》

五、《如何從 0 到 1 搭建生鮮 B2B 的技術體系(B2B 技術共享第五篇)》

六、《宋小菜技術如何應對生鮮 B2B 業務的快速變化(B2B 技術共享第六篇)》

七、《生鮮 B2B 技術平臺的前端團隊該如何搭建(B2B 技術共享第七篇)》

八、《宋小菜有關「能力」的設計和思考(B2B 技術共享第八篇)》

九、《服務拆分的設計和思考(B2B 技術共享第九篇)》

相關文章
相關標籤/搜索