天天看點

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

作者:大資料架構師

資料同步

上面講解了資料一緻性的解決方案,這一篇來講講服務之間的資料依賴問題,還是先來說說具體的業務場景。

業務場景:如何解決微服務之間的資料依賴問題

在某個供應鍊系統中,存在商品、訂單、采購這3個服務,它們的主資料部分結構表如下。

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

而在設計這個系統時,需要滿足以下兩點需求。

1)根據商品的型号、分類、生成年份、編碼等查找訂單。

2)根據商品的型号、分類、生成年份、編碼等查找訂單或采購單。

初期方案是這樣設計的:首先,按照嚴格的微服務劃分原則,把商品相關的職責放在商品服務中,是以在訂單與采購單查詢過程中,如果查詢字段包含商品字段,就按照如下順序進行查詢。

1)先根據商品字段調用商品服務,然後傳回比對的商品資訊。

2)在訂單服務或采購服務中,通過IN語句比對商品ID,再關聯查詢對應的單據。

訂單的整個查詢流程如圖14-1所示。

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

• 圖14-1 查詢流程

初期方案設計完成後,很快就碰到了一系列問題。

1)随着商品數量的增多,比對到的商品越來越多,于是訂單和采購服務中包含IN語句的資料查詢效率越來越低。

2)商品服務作為一個核心服務,依賴它的服務越來越多,同時随着商品資料量的增長,商品服務開始不堪重負,響應也變慢,還存在請求逾時的情況。

3)因為商品服務逾時,使得依賴它的服務處理請求也經常失敗。

這就導緻業務方查詢訂單或者采購單時,每次隻要加上商品ID這個關鍵字,查詢效率就會很低,而且經常失敗,于是團隊想出了一個新的方案——備援。

資料備援方案

資料備援方案即在訂單、采購單中儲存一些商品的字段資訊,具體如下。

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

通過這樣的方案,每次查詢訂單或采購單時,就不需要依賴商品服務了,但是商品如果有更新,怎麼同步備援的資料呢?有兩種處理辦法。

1)每次更新商品時,先調用訂單與采購服務,然後更新商品的備援資料。

2)每次更新商品時,釋出一條消息,訂單與采購服務各自訂閱這條消息,再各自更新商品的備援資料。

前面講解資料一緻性問題時曾提到過類似的場景。

那麼這兩種處理辦法會出現什麼問題?

先說說第一種處理辦法:如果商品服務每次更新商品時,都需要調用訂單與采購服務,然後再更新備援資料,則會出現以下兩個問題。

1)資料一緻性問題:如果訂單和采購服務的備援資料更新失敗,整個操作就要復原,商品服務的開發人員肯定不希望如此,因為備援資料并又不是商品服務的核心需求,為什麼要因為邊緣流程而阻斷了自身的核心流程?

2)依賴問題:從職責來說,商品服務應該關注商品本身,但是現在商品服務還需要調用訂單、采購的服務。而且作為一個核心服務,依賴它的服務太多了,即後續每次商品服務更新商品時,都需要調用訂單備援資料更新、采購備援資料更新、門店庫存備援資料更新、營運備援資料更新等衆多服務。

商品服務本意是要設計成底層服務,但是如果使用這種方案,它要依賴于很多其他服務,與原來作為底層服務的初衷相悖。是以,第一個方案直接被否決了。

下面講第二種處理辦法。通過消息釋出訂閱的方案有以下幾點好處。

1)商品無須再調用其他服務,它隻需要關注自身的邏輯,最多生成一條消息到MQ。

2)如果訂單、采購等服務的備援資料更新失敗了,隻需要使用消息重試機制就可以保證資料的一緻性。

此時方案的架構如圖14-2所示。

這樣的方案已經比較完善了,而且開發人員基本都是這麼做的,不過這個方案存在以下幾個問題。

1)商品表的備援資料需要更新(商品分類ID和生産批号ID)。

在這個項目中,僅僅把備援資料進行儲存遠遠不夠,還需要将商品分類與生産批号的清單進行關聯查詢。也就是說,每個服務不僅要訂閱商品變更一種消息,還需要訂閱商品分類、商品生産批号的變更消息。

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

• 圖14-2 基于消息訂閱的資料同步方案

而且這裡隻是列舉了一部分的結構,事實上,商品表中還有很多其他的字段是備援的,比如保修類型、包換類型等。為了更新這些備援資料,采購服務與訂單服務往往需要訂閱近10種消息,基本上要把商品的一小半邏輯複制過來。

2)每個依賴的服務需要重複實作備援資料更新同步的邏輯。前面講過,采購、訂單及其他的服務都需要依賴商品資料,是以每個服務都需要把備援資料的訂閱、更新邏輯做一遍,最終重複代碼就會很多。

3)MQ消息類型過多。聯調時最麻煩的是MQ之間的關聯,如果是接口聯調還比較簡單,因為調用伺服器的接口相對可控而且比較容易追溯,但是如果是消息聯調,因為經常不知道某條消息被哪台服務節點消費了,為了讓特定的伺服器消費特定的消息,就需要臨時改動雙方的代碼,然而聯調完成後,開發人員常常忘記把代碼改回來。

因為并不希望出現這麼多消息,特别是備援資料這種非核心需求,最終項目組決定使用一個特别的同步備援資料的方案,接下來進一步說明。

解耦業務邏輯的資料同步方案

解耦業務邏輯的資料同步方案設計思路是這樣的。

1)将商品及商品相關的一些表(比如分類表、生産批号表、保修類型、包換類型等)實時同步到需要依賴和使用它們的服務的資料庫,并且保持表結構不變。

2)在查詢采購、訂單等服務中的資料時,直接關聯同步過來的商品相關表。

3)不允許采購、訂單等服務修改商品相關表。

此時,整個方案架構如圖14-3所示。

以上方案能輕松避免以下兩個問題。

1)商品無須依賴其他服務,如果其他服務的備援資料同步失敗,它也不需要復原自身的流程。

2)采購、訂單等服務無須關注備援資料的同步。

架構師帶你搞明白微服務進階場景實戰:服務之間的資料依賴問題

• 圖14-3 解耦業務邏輯的資料同步方案

這個方案的缺點是增加了訂單、采購等資料庫的存儲空間(因為增加了商品相關表)。

計算後會發現,之前資料備援的方案中每個訂單都需要儲存一份商品的備援資料,假設訂單總量是1000萬,商品總數是10萬。如果采用之前資料備援的方案,1000萬條訂單記錄就要增加1000萬條商品的備援資料,相比之下,目前的方案更省空間,因為隻增加了10萬條商品的資料。

那麼如何實時同步相關表資料呢?請看下節講解。

本文給大家講解的内容是微服務進階場景實戰:資料同步

  1. 下篇文章給大家講解的内容是微服務進階場景實戰:基于Bifrost的資料同步方案
  2. 覺得文章不錯的朋友可以轉發此文關注小編;
  3. 感謝大家的支援!!

繼續閱讀