0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

微服務(wù)之間涉及到的數(shù)據(jù)依賴(lài)問(wèn)題應(yīng)該怎么處理呢?

jf_ro2CN3Fa ? 來(lái)源:CSDN ? 2023-06-15 10:05 ? 次閱讀

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

商品

ID 名稱(chēng) 分類(lèi) 型號(hào) 生產(chǎn)年份 編碼

訂單和子訂單

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

采購(gòu)單和子訂單

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

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

根據(jù)商品的型號(hào)/分類(lèi)/生成年份/編碼 等查找訂單;

根據(jù)商品的型號(hào)/分類(lèi)/生成年份/編碼 等查找采購(gòu)訂單。

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

先根據(jù)商品字段調(diào)用商品的服務(wù),然后返回匹配的商品信息

在訂單或采購(gòu)單中,通過(guò) IN 語(yǔ)句匹配商品 ID,再關(guān)聯(lián)查詢(xún)對(duì)應(yīng)的單據(jù)。

為了方便理解這個(gè)過(guò)程,訂單查詢(xún)流程圖如下圖所示:

03fa31c2-0b1d-11ee-962d-dac502259ad0.png

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

隨著商品數(shù)量的增多,匹配的商品越來(lái)越多,于是訂單服務(wù)中包含 IN 語(yǔ)句的查詢(xún)效率越來(lái)越慢

商品作為一個(gè)核心服務(wù),依賴(lài)它的服務(wù)越來(lái)越多,同時(shí)隨著商品數(shù)據(jù)量的增長(zhǎng),商品服務(wù)已不堪重負(fù),響應(yīng)速度也變慢,還存在請(qǐng)求超時(shí) 的情況

由于商品服務(wù)超時(shí),相關(guān)服務(wù)處理請(qǐng)求經(jīng)常失敗。

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

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

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

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

商品

ID 名稱(chēng) 分類(lèi)ID 型號(hào) 生產(chǎn)年份ID 編碼

訂單和子訂單

訂單ID 下單時(shí)間 客戶(hù) 總金額
子訂單ID 商品ID 單價(jià) 數(shù)量 商品名稱(chēng) 商品分類(lèi)ID 商品型號(hào) 生產(chǎn)批次ID

采購(gòu)單和子訂單

采購(gòu)單ID 下單時(shí)間 供應(yīng)商 總金額
采購(gòu)子訂單ID 商品ID 單價(jià) 數(shù)量 商品名稱(chēng) 商品分類(lèi)ID 商品型號(hào) 生產(chǎn)批次ID

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

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

每次更新商品時(shí),先調(diào)用訂單與采購(gòu)服務(wù),再更新商品的冗余數(shù)據(jù)。

每次更新商品時(shí),先發(fā)布一條消息,訂單與采購(gòu)服務(wù)各自訂閱這條消息后,再各自更新商品冗余數(shù)據(jù)。

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

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

數(shù)據(jù)一致性問(wèn)題 :如果訂單與采購(gòu)的冗余數(shù)據(jù)更新失敗了,整個(gè)操作都需要回滾。這時(shí)商品服務(wù)的開(kāi)發(fā)人員肯定不樂(lè)意,因?yàn)槿哂鄶?shù)據(jù)不是商品服務(wù)的核心需求,不能因?yàn)檫吘壛鞒套钄嗔俗陨淼暮诵牧鞒獭?/p>

依賴(lài)問(wèn)題 :從職責(zé)來(lái)說(shuō),商品服務(wù)應(yīng)該只關(guān)注商品本身,但是現(xiàn)在商品還需要調(diào)用訂單與采購(gòu)服務(wù)。而且,依賴(lài)商品這個(gè)核心服務(wù)的服務(wù)實(shí)在是太多了,也就導(dǎo)致后續(xù)商品服務(wù)每次更新商品時(shí),都需要調(diào)用更新訂單冗余數(shù)據(jù)、更新采購(gòu)冗余數(shù)據(jù)、更新門(mén)店庫(kù)存冗余數(shù)據(jù)、更新運(yùn)營(yíng)冗余數(shù)據(jù)等一大堆服務(wù)。那么商品到底是下游服務(wù)還是上游服務(wù)?還能不能安心當(dāng)?shù)讓雍诵姆?wù)?

因此,第一個(gè)解決辦法直接被我們否決了,即我們采取的第二個(gè)解決辦法——通過(guò)消息發(fā)布訂閱的方案 ,因?yàn)樗嬖谌缦?2 點(diǎn) 優(yōu)勢(shì):

商品無(wú)須調(diào)用其他服務(wù),它只需要關(guān)注自身邏輯即可,頂多多生成一條消息送到 MQ 。

如果訂單、采購(gòu)等服務(wù)的更新冗余數(shù)據(jù)失敗了,我們使用消息重試機(jī)制 就可以了,最終能保證數(shù)據(jù)的一致性。

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

040a9b20-0b1d-11ee-962d-dac502259ad0.png

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

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

訂單ID 下單時(shí)間 客戶(hù) 總金額
子訂單ID 商品ID 單價(jià) 數(shù)量 商品名稱(chēng) 商品分類(lèi)ID 商品型號(hào) 生產(chǎn)批次ID

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

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

3、MQ 消息類(lèi)型太多了:聯(lián)調(diào)時(shí)最麻煩的是 MQ 之間的聯(lián)動(dòng),如果是接口聯(lián)調(diào)還好說(shuō),因?yàn)檎{(diào)用哪個(gè)服務(wù)器的接口相對(duì)可控而且比較好追溯;如果是消息聯(lián)調(diào)就比較麻煩,因?yàn)槲覀兂32恢滥硹l消息被哪臺(tái)服務(wù)節(jié)點(diǎn)消費(fèi)了,為了讓特定的服務(wù)器消費(fèi)特定的消息,我們就需要臨時(shí)改動(dòng)雙方的代碼。不過(guò)聯(lián)調(diào)完成后,我們經(jīng)常忘了改回原代碼。

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

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

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

將商品及商品相關(guān)的一些表(比如分類(lèi)表、生產(chǎn)批號(hào)表、保修類(lèi)型、包換類(lèi)型等)實(shí)時(shí)同步到需要依賴(lài)使用它們的服務(wù)的數(shù)據(jù)庫(kù),并且保持表結(jié)構(gòu)不變;

在查詢(xún)采購(gòu)、訂單等服務(wù)時(shí),直接關(guān)聯(lián)同步過(guò)來(lái)的商品相關(guān)表;

不允許采購(gòu)、訂單等服務(wù)修改商品相關(guān)表。

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

0420131a-0b1d-11ee-962d-dac502259ad0.png

以上方案就能輕松解決如下兩個(gè)問(wèn)題:

商品無(wú)須依賴(lài)其他服務(wù),如果其他服務(wù)的冗余數(shù)據(jù)同步失敗,它也不需要回滾自身的流程;

采購(gòu)、訂單等服務(wù)無(wú)須關(guān)注冗余數(shù)據(jù)的同步。

不過(guò),該方案的“缺點(diǎn) ”是增加了訂單、采購(gòu)等數(shù)據(jù)庫(kù)的存儲(chǔ)空間(因?yàn)樵黾恿松唐废嚓P(guān)表)。

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

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

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

根據(jù)這五點(diǎn)要求,我們?cè)谑忻嫔险伊艘蝗?,發(fā)現(xiàn)了 Canal 、DebeziumDataX 、Databus 、Flinkx 、Bifrost 這幾款開(kāi)源中間件,它們之間的區(qū)別如下表所示:

04534faa-0b1d-11ee-962d-dac502259ad0.png

從對(duì)比表中來(lái)看,比較貼近我們需求的開(kāi)源中間件是 Bifrost ,原因如下:

它的界面管理不錯(cuò);

它的架構(gòu)比較簡(jiǎn)單,出現(xiàn)問(wèn)題后,我們可以自行調(diào)查,之后就算作者不維護(hù)了也可以自我維護(hù),相對(duì)比較可控。

作者更新活躍;

自帶監(jiān)控報(bào)警功能。

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

046fa100-0b1d-11ee-962d-dac502259ad0.png

3、最終效果

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

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

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





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:微服務(wù)之間的數(shù)據(jù)依賴(lài)問(wèn)題,該如何解決?

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    開(kāi)發(fā)板上涉及到的模塊

    開(kāi)發(fā)板上涉及到的模塊
    發(fā)表于 09-23 18:59

    如何用ACM簡(jiǎn)化你的Spring Cloud微服務(wù)環(huán)境配置管理

    服務(wù)的基本行為,或者不同環(huán)境之間的配置差異很大,那么你可能就只能在一套環(huán)境中發(fā)現(xiàn)某個(gè)特定的問(wèn)題,這是極其痛苦的事情。 所以,如果存在不同環(huán)境之間的配置差異,應(yīng)該如何在部署流程中對(duì)其進(jìn)行
    發(fā)表于 02-02 14:18

    使用阿里云ACM簡(jiǎn)化你的Spring Cloud微服務(wù)環(huán)境配置管理

    的配置差異很大,那么你可能就只能在一套環(huán)境中發(fā)現(xiàn)某個(gè)特定的問(wèn)題,這是極其痛苦的事情。所以,如果存在不同環(huán)境之間的配置差異,應(yīng)該如何在部署流程中對(duì)其進(jìn)行處理?一種方法是對(duì)每個(gè)環(huán)境創(chuàng)建不
    發(fā)表于 07-04 17:16

    區(qū)塊鏈應(yīng)用涉及到哪些算法?

    區(qū)塊鏈技術(shù)的應(yīng)用涉及到哪些算法模型?
    發(fā)表于 03-27 11:21

    微服務(wù)架構(gòu)和CQRS架構(gòu)基本概念介紹

    邊界思維,微服務(wù)的目的是為了從業(yè)務(wù)角度拆分(職責(zé)分離)當(dāng)前業(yè)務(wù)領(lǐng)域的不同業(yè)務(wù)模塊不同的服務(wù),每個(gè)微服務(wù)之間
    發(fā)表于 05-22 09:03

    中斷系統(tǒng)涉及到哪些問(wèn)題

    在開(kāi)始寫(xiě)中斷函數(shù)之前,我們來(lái)一起回顧一下,單片機(jī)的中斷系統(tǒng)。中斷的意思(學(xué)習(xí)過(guò)微機(jī)原理與接口技術(shù)的同學(xué),沒(méi)學(xué)過(guò)單片機(jī),也應(yīng)該知道),我們?cè)谶@里就不講了,首先來(lái)回憶下中斷系統(tǒng)涉及到哪些問(wèn)題。(1)中斷
    發(fā)表于 07-15 09:32

    51單片機(jī)工程涉及到的模塊包括哪些?

    51單片機(jī)工程涉及到的模塊包括哪些?如何去編寫(xiě)51單片機(jī)工程涉及的模塊代碼?
    發(fā)表于 07-19 08:38

    嵌入式需要涉及到哪些知識(shí)

    開(kāi)發(fā)linux嵌入式產(chǎn)品的過(guò)程是怎樣的?嵌入式需要涉及到哪些知識(shí)
    發(fā)表于 11-12 07:35

    數(shù)據(jù)鏈路層發(fā)送與接收的處理過(guò)程及涉及到的模塊

    數(shù)據(jù)鏈路層包括發(fā)送和接收兩個(gè)部分,本章主要介紹數(shù)據(jù)流從進(jìn)入發(fā)射器的數(shù)據(jù)鏈路層從接收器的數(shù)據(jù)
    發(fā)表于 02-08 10:27 ?1w次閱讀

    運(yùn)維是如何看待微服務(wù)和容器的

    微服務(wù)在帶來(lái)良好的設(shè)計(jì)和架構(gòu)理念的同時(shí),也帶來(lái)了運(yùn)維上的額外復(fù)雜性,尤其是在服務(wù)部署和服務(wù)監(jiān)控上。那么,運(yùn)維是如何看待微服務(wù)和容器的?傳統(tǒng)
    發(fā)表于 09-30 17:24 ?0次下載
    運(yùn)維是如何看待<b class='flag-5'>微服務(wù)</b>和容器的

    自動(dòng)駕駛技術(shù)涉及到的AI科技

    隨著人工智能技術(shù)的不斷發(fā)展,人們急切的希望這項(xiàng)技術(shù)能夠盡快的落地成熟,那么自動(dòng)駕駛技術(shù)到底涉及到哪些科技?現(xiàn)有的產(chǎn)品到底是處于什么階段?
    的頭像 發(fā)表于 11-25 09:26 ?6206次閱讀
    自動(dòng)駕駛技術(shù)<b class='flag-5'>涉及到</b>的AI科技

    微服務(wù)和容器之間的有何關(guān)系?

    現(xiàn)在一提到微服務(wù),有很多人會(huì)想到容器技術(shù)(這里說(shuō)到的容器技術(shù)是指docker)。那么微服務(wù)和容器之間到底有什么關(guān)系,我來(lái)簡(jiǎn)要和大家探討下。先拋出結(jié)論:
    的頭像 發(fā)表于 02-01 01:58 ?6151次閱讀

    微服務(wù)循環(huán)依賴(lài)調(diào)用引發(fā)的血案

    順著測(cè)試匯報(bào)的出現(xiàn)問(wèn)題的場(chǎng)景,跟蹤調(diào)用鏈上相關(guān)服務(wù)的日志,發(fā)現(xiàn)出現(xiàn)了微服務(wù)之間依賴(lài)調(diào)用。大致情況可以抽象如下所示(圖中所有調(diào)用都是 http 協(xié)議)
    的頭像 發(fā)表于 01-16 10:28 ?716次閱讀

    微服務(wù)架構(gòu)中的服務(wù)之間如何互相調(diào)用?

    微服務(wù)架構(gòu)中,需要調(diào)用很多服務(wù)才能完成一項(xiàng)功能。服務(wù)之間如何互相調(diào)用就變成微服務(wù)架構(gòu)中的一個(gè)關(guān)鍵問(wèn)題。
    的頭像 發(fā)表于 01-31 09:46 ?2208次閱讀

    從分層架構(gòu)微服務(wù)架構(gòu)介紹(五)

    本文要介紹的是 服務(wù)化架構(gòu) (Service-Based Architecture, SBA )。 SBA 可以看成是單體架構(gòu)和微服務(wù)架構(gòu)之間的一個(gè)折中方案,它也是按照業(yè)務(wù)領(lǐng)域進(jìn)行服務(wù)
    的頭像 發(fā)表于 05-10 17:02 ?848次閱讀
    從分層架構(gòu)<b class='flag-5'>到</b><b class='flag-5'>微服務(wù)</b>架構(gòu)介紹(五)