<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          微服務(wù)之間的數(shù)據(jù)依賴問題,該如何解決?

          共 7038字,需瀏覽 15分鐘

           ·

          2024-08-19 10:30

          來源:網(wǎng)絡(luò)

          ?? 歡迎加入小哈的星球,你將獲得: 專屬的項目實戰(zhàn) / 1v1 提問 / Java 學(xué)習(xí)路線 / 學(xué)習(xí)打卡 / 每月贈書 / 社群討論

          • 新項目:《從零手?jǐn)]:仿小紅書(微服務(wù)架構(gòu))》 正在持續(xù)爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 點擊查看項目介紹
          • 《從零手?jǐn)]:前后端分離博客項目(全棧開發(fā))》 2期已完結(jié),演示鏈接:http://116.62.199.48/;

          截止目前,累計輸出 54w+ 字,講解圖 2330+ 張,還在持續(xù)爆肝中.. 后續(xù)還會上新更多項目,目標(biāo)是將 Java 領(lǐng)域典型的項目都整一波,如秒殺系統(tǒng), 在線商城, IM 即時通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),解鎖全部項目,已有1900+小伙伴加入

          • 1、數(shù)據(jù)冗余的方案
          • 2、解耦業(yè)務(wù)邏輯的數(shù)據(jù)同步方案
          • 3、最終效果

          曾經(jīng)設(shè)計的一個供應(yīng)鏈系統(tǒng)中,存在商品 、銷售訂單采購 這三個服務(wù),它們的主數(shù)據(jù)的部分結(jié)構(gòu)如下所示:

          商品

          ID 名稱 分類 型號 生產(chǎn)年份 編碼






          訂單和子訂單

          訂單ID 下單時間 客戶 總金額 子訂單ID 商品ID 單價 數(shù)量








          采購單和子訂單

          采購單ID 下單時間 供應(yīng)商 總金額 采購子訂單ID 商品ID 單價 數(shù)量








          在設(shè)計這個供應(yīng)鏈系統(tǒng)時,我們需要滿足以下兩個需求:

          • 根據(jù)商品的型號/分類/生成年份/編碼 等查找訂單;
          • 根據(jù)商品的型號/分類/生成年份/編碼 等查找采購訂單。

          初期我們的方案是這樣設(shè)計的:嚴(yán)格按照的微服務(wù)劃分原則將商品相關(guān)的職責(zé)存放在商品系統(tǒng)中。因此,在查詢訂單與采購單時,如果查詢字段包含商品字段,我們需要按照如下順序進(jìn)行查詢:

          • 先根據(jù)商品字段調(diào)用商品的服務(wù),然后返回匹配的商品信息;
          • 在訂單或采購單中,通過 IN 語句匹配商品 ID,再關(guān)聯(lián)查詢對應(yīng)的單據(jù)。

          為了方便理解這個過程,訂單查詢流程圖如下圖所示:

          圖片

          初期方案設(shè)計完后,很快我們就遇到了一系列問題:

          • 隨著商品數(shù)量的增多,匹配的商品越來越多,于是訂單服務(wù)中包含 IN 語句的查詢效率越來越慢
          • 商品作為一個核心服務(wù),依賴它的服務(wù)越來越多,同時隨著商品數(shù)據(jù)量的增長,商品服務(wù)已不堪重負(fù),響應(yīng)速度也變慢,還存在請求超時 的情況
          • 由于商品服務(wù)超時,相關(guān)服務(wù)處理請求經(jīng)常失敗。

          結(jié)果就是業(yè)務(wù)方每次查詢訂單或采購單時,只要帶上了商品這個關(guān)鍵字,查詢效率就會很慢而且老是失敗。于是,我們重新想了一個新方案——數(shù)據(jù)冗余 ,下面我們一起來看下。

          1、數(shù)據(jù)冗余的方案

          數(shù)據(jù)冗余說白了就是在訂單、采購單中保存一些商品字段 信息。

          為了方便理解,我們借助上面實際業(yè)務(wù)場景具體說明下,看看兩者的區(qū)別。

          商品

          ID 名稱 分類ID 型號 生產(chǎn)年份ID 編碼






          訂單和子訂單

          訂單ID 下單時間 客戶 總金額



          子訂單ID 商品ID 單價 數(shù)量 商品名稱 商品分類ID 商品型號 生產(chǎn)批次ID

          采購單和子訂單

          采購單ID 下單時間 供應(yīng)商 總金額



          采購子訂單ID 商品ID 單價 數(shù)量 商品名稱 商品分類ID 商品型號 生產(chǎn)批次ID

          調(diào)整架構(gòu)方案后,每次查詢時,我們就可以不再依賴商品服務(wù)了 。

          但是,如果商品進(jìn)行了更新,我們?nèi)绾瓮饺哂嗟臄?shù)據(jù)呢?在此分享2種 解決辦法。

          1. 每次更新商品時,先調(diào)用訂單與采購服務(wù),再更新商品的冗余數(shù)據(jù)。
          2. 每次更新商品時,先發(fā)布一條消息,訂單與采購服務(wù)各自訂閱這條消息后,再各自更新商品冗余數(shù)據(jù)。

          那么這2種方案會出現(xiàn)哪些問題呢?

          如果商品服務(wù)每次更新商品都要調(diào)用訂單與采購服務(wù),然后再更新冗余數(shù)據(jù),則會出現(xiàn)以下兩種問題。

          • 數(shù)據(jù)一致性問題 :如果訂單與采購的冗余數(shù)據(jù)更新失敗了,整個操作都需要回滾。這時商品服務(wù)的開發(fā)人員肯定不樂意,因為冗余數(shù)據(jù)不是商品服務(wù)的核心需求,不能因為邊緣流程阻斷了自身的核心流程。
          • 依賴問題 :從職責(zé)來說,商品服務(wù)應(yīng)該只關(guān)注商品本身,但是現(xiàn)在商品還需要調(diào)用訂單與采購服務(wù)。而且,依賴商品這個核心服務(wù)的服務(wù)實在是太多了,也就導(dǎo)致后續(xù)商品服務(wù)每次更新商品時,都需要調(diào)用更新訂單冗余數(shù)據(jù)、更新采購冗余數(shù)據(jù)、更新門店庫存冗余數(shù)據(jù)、更新運(yùn)營冗余數(shù)據(jù)等一大堆服務(wù)。那么商品到底是下游服務(wù)還是上游服務(wù)?還能不能安心當(dāng)?shù)讓雍诵姆?wù)?

          因此,第一個解決辦法直接被我們否決了,即我們采取的第二個解決辦法——通過消息發(fā)布訂閱的方案 ,因為它存在如下 2 點 優(yōu)勢:

          • 商品無須調(diào)用其他服務(wù),它只需要關(guān)注自身邏輯即可,頂多多生成一條消息送到 MQ 。
          • 如果訂單、采購等服務(wù)的更新冗余數(shù)據(jù)失敗了,我們使用消息重試機(jī)制 就可以了,最終能保證數(shù)據(jù)的一致性。

          此時,我們的架構(gòu)方案如下圖所示:

          圖片

          這個方案看起來已經(jīng)挺完美了,而且市面上基本也是這么做的,不過該方案存在如下幾個問題。

          1、在這個方案中,僅僅保存冗余數(shù)據(jù)還遠(yuǎn)遠(yuǎn)不夠,我們還需要將商品分類與生產(chǎn)批號的清單進(jìn)行關(guān)聯(lián)查詢。也就是說,每個服務(wù)不只是訂閱商品變更這一種消息,還需要訂閱商品分類、商品生產(chǎn)批號變更等消息。下面請注意查看訂單表結(jié)構(gòu)的紅色加粗部分內(nèi)容。

          訂單ID 下單時間 客戶 總金額



          子訂單ID 商品ID 單價 數(shù)量 商品名稱 商品分類ID 商品型號 生產(chǎn)批次ID

          以上只是列舉了一部分的結(jié)構(gòu),事實上,商品表中還有很多字段存在冗余,比如保修類型、包換類型等。為了更新這些冗余數(shù)據(jù),采購服務(wù)與訂單服務(wù)往往需要訂閱近十種消息,因此,我們基本上需要把商品的一小半邏輯復(fù)制過來。

          2、每個依賴的服務(wù)需要重復(fù)實現(xiàn)冗余數(shù)據(jù)更新同步的邏輯。前面我們講了采購、訂單及其他服務(wù)都需要依賴商品數(shù)據(jù),因此每個服務(wù)需要將冗余數(shù)據(jù)的訂閱、更新邏輯做一遍,最終重復(fù)的代碼就會很多。

          3、MQ 消息類型太多了:聯(lián)調(diào)時最麻煩的是 MQ 之間的聯(lián)動,如果是接口聯(lián)調(diào)還好說,因為調(diào)用哪個服務(wù)器的接口相對可控而且比較好追溯;如果是消息聯(lián)調(diào)就比較麻煩,因為我們常常不知道某條消息被哪臺服務(wù)節(jié)點消費(fèi)了,為了讓特定的服務(wù)器消費(fèi)特定的消息,我們就需要臨時改動雙方的代碼。不過聯(lián)調(diào)完成后,我們經(jīng)常忘了改回原代碼。

          為此,我們不希望針對冗余數(shù)據(jù)這種非核心需求出現(xiàn)如此多的問題,最終決定使用一個特別的同步冗余數(shù)據(jù)方案,接下來我們進(jìn)一步說明。

          2、解耦業(yè)務(wù)邏輯的數(shù)據(jù)同步方案

          解耦業(yè)務(wù)邏輯的數(shù)據(jù)同步方案的設(shè)計思路是這樣的:

          • 將商品及商品相關(guān)的一些表(比如分類表、生產(chǎn)批號表、保修類型、包換類型等)實時同步到需要依賴使用它們的服務(wù)的數(shù)據(jù)庫,并且保持表結(jié)構(gòu)不變;
          • 在查詢采購、訂單等服務(wù)時,直接關(guān)聯(lián)同步過來的商品相關(guān)表;
          • 不允許采購、訂單等服務(wù)修改商品相關(guān)表。

          此時,整個方案的架構(gòu)如下圖所示:

          圖片

          以上方案就能輕松解決如下兩個問題:

          • 商品無須依賴其他服務(wù),如果其他服務(wù)的冗余數(shù)據(jù)同步失敗,它也不需要回滾自身的流程;
          • 采購、訂單等服務(wù)無須關(guān)注冗余數(shù)據(jù)的同步。

          不過,該方案的“缺點 ”是增加了訂單、采購等數(shù)據(jù)庫的存儲空間(因為增加了商品相關(guān)表)。

          仔細(xì)計算后,我們發(fā)現(xiàn)之前數(shù)據(jù)冗余的方案中每個訂單都需要保存一份商品的冗余數(shù)據(jù),假設(shè)訂單總數(shù)是 N,商品總數(shù)是 M,而 N 一般遠(yuǎn)遠(yuǎn)大于 M。因此,在之前數(shù)據(jù)冗余的方案中,N 條訂單就會產(chǎn)生 N 條商品的冗余數(shù)據(jù)。相比之下,解耦業(yè)務(wù)邏輯的數(shù)據(jù)同步方案更省空間,因為只增加了 M 條商品的數(shù)據(jù)。

          此時問題又來了,如何實時同步相關(guān)表的數(shù)據(jù)呢?

          我們直接找一個現(xiàn)成的開源中間件就可以了,不過它需要滿足支持實時同步、支持增量同步、不用寫業(yè)務(wù)邏輯、支持 MySQL 之間同步、活躍度高這五點要求。

          根據(jù)這五點要求,我們在市面上找了一圈,發(fā)現(xiàn)了 Canal 、Debezium 、DataXDatabus 、FlinkxBifrost 這幾款開源中間件,它們之間的區(qū)別如下表所示:

          圖片

          從對比表中來看,比較貼近我們需求的開源中間件是 Bifrost ,原因如下:

          1. 它的界面管理不錯;
          2. 它的架構(gòu)比較簡單,出現(xiàn)問題后,我們可以自行調(diào)查,之后就算作者不維護(hù)了也可以自我維護(hù),相對比較可控。
          3. 作者更新活躍;
          4. 自帶監(jiān)控報警功能。

          因此,最終我們使用了 Bifrost 開源中間件,此時整個方案的架構(gòu)如下圖所示:

          圖片

          3、最終效果

          整個架構(gòu)方案上線后,商品數(shù)據(jù)的同步還算比較穩(wěn)定,此時商品服務(wù)的開發(fā)人員只需要關(guān)注自身邏輯,無須再關(guān)注使用數(shù)據(jù)的人。如果需要關(guān)聯(lián)使用商品數(shù)據(jù)的訂單,采購服務(wù)的開發(fā)人員也無須關(guān)注商品數(shù)據(jù)的同步問題,只需要在查詢時加上關(guān)聯(lián)語句即可,實現(xiàn)了雙贏。

          然而,唯一讓我們擔(dān)心的是 Bifrost 不支持集群,沒法保障高可用性。不過,到目前為止,它還沒有出現(xiàn)宕機(jī)的情況,反而是那些部署多臺節(jié)點負(fù)載均衡的后臺服務(wù)常常會出現(xiàn)宕機(jī)。

          最終,我們總算解決了服務(wù)之間數(shù)據(jù)依賴的問題。

          ?? 歡迎加入小哈的星球,你將獲得: 專屬的項目實戰(zhàn) / 1v1 提問 / Java 學(xué)習(xí)路線 / 學(xué)習(xí)打卡 / 每月贈書 / 社群討論

          • 新項目:《從零手?jǐn)]:仿小紅書(微服務(wù)架構(gòu))》 正在持續(xù)爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 點擊查看項目介紹;
          • 《從零手?jǐn)]:前后端分離博客項目(全棧開發(fā))》 2期已完結(jié),演示鏈接:http://116.62.199.48/;

          截止目前,累計輸出 54w+ 字,講解圖 2330+ 張,還在持續(xù)爆肝中.. 后續(xù)還會上新更多項目,目標(biāo)是將 Java 領(lǐng)域典型的項目都整一波,如秒殺系統(tǒng), 在線商城, IM 即時通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),解鎖全部項目,已有1900+小伙伴加入


              
                 

          1. 我的私密學(xué)習(xí)小圈子~

          2. 船新 IDEA 2024.2 正式發(fā)布,新特性真香!

          3. 使用 Java + WebSocket 實現(xiàn)簡單實時雙人協(xié)同 pk 答題

          4. Java8 中一個極其強(qiáng)悍的新接口,很多人沒用過

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點“在看”,關(guān)注公眾號并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          PS:因公眾號平臺更改了推送規(guī)則,如果不想錯過內(nèi)容,記得讀完點一下在看,加個星標(biāo),這樣每次新文章推送才會第一時間出現(xiàn)在你的訂閱列表里。

          “在看”支持小哈呀,謝謝啦

          瀏覽 79
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋婷婷五月天 | 日韩精品人妻成人免费视频 | 国产在线成人视频 | 做爱网站在线观看 | 亚洲高清无码在线免费观看 |