最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分布式面試消息隊(duì)列解決消息重復(fù)保證消息順序

 更新時(shí)間:2022年03月09日 17:36:05   作者:Q.E.D  
這篇文章主要介紹了分布式面試問題:分布式消息隊(duì)列如何解決消息重復(fù)并保證消息順序面試問題解答,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

引言

我在《項(xiàng)目中為什么要使用消息隊(duì)列》中列舉了兩個(gè)使用消息隊(duì)列的例子。

(1)收銀系統(tǒng),確認(rèn)收款成功,通過MQ通知給物流系統(tǒng)發(fā)貨。

(2)消費(fèi)積分,用戶每消費(fèi)一筆給用戶增加一定積分,京東豆,信用卡積分,2020年如果還沒倒閉的電商平臺(tái)中,可以100%的確定訂單系統(tǒng)和積分/獎(jiǎng)勵(lì)系統(tǒng)不是耦合在一起的。

這些都是很典型的使用消息隊(duì)列的場景。

那么問題來了,想象一下,積分系統(tǒng)收到同一個(gè)用戶同一個(gè)訂單兩條相同的消息會(huì)怎樣?積分會(huì)被加兩遍嗎?針對這個(gè)問題,面試官又開始一輪三連問,你還能扛得過去嗎?

這不是“面試造火箭,工作擰螺絲”,消息重復(fù),消息積壓這類問題是你入職后工作中真真切切會(huì)遇到的,不是面試官故意刁難你。

1、面試官:

那你有考慮過消息重復(fù)問題怎么解決嗎?

問題分析:還是拿上面的例子分析,積分系統(tǒng)收到同一個(gè)用戶同一個(gè)訂單兩條相同的消息會(huì)怎樣,先不管因?yàn)槭裁丛蛳l(fā)了兩次,積分會(huì)被加兩遍嗎?

產(chǎn)品經(jīng)理說: 那肯定不行呀,花100塊給100個(gè)積分,積分沒有買一送一服務(wù)。

訂單系統(tǒng)RD說: 我這邊沒辦法100%保證積分廣播只發(fā)一次,萬一出個(gè)bug同一筆消費(fèi)積分,消息可能發(fā)了幾百次也不好說。

答:產(chǎn)品說不行,訂單RD說他不保證消息不重復(fù),Kafka架構(gòu)RD也說無法保證消息不重復(fù),那怎么辦?我是負(fù)責(zé)積分系統(tǒng)的,針對消息重復(fù)問題,我會(huì)針對積分累計(jì)接口做**“冪等”**設(shè)計(jì),這個(gè)問題,首先我們應(yīng)該從上游就做消息去重處理,但是我們不能100%相信上游系統(tǒng)一定可靠,我是消息消費(fèi)端,只有我這邊做了冪等設(shè)計(jì)才能完全避免這種和錢相關(guān)的bug,畢竟如果依賴上游,真的出了用戶消費(fèi)100元最后加了100w積分,這鍋重要還是我們背。

我可以根據(jù)用戶訂單號(hào)或者流水號(hào)做強(qiáng)冪等,每成功操作一次加積分就記錄下來,即使消息重負(fù)了,我只要判斷同一個(gè)訂單號(hào)已經(jīng)操作加分了,后續(xù)我們就不會(huì)再做任何操作了。

隨手寫了一段偽代碼給面試官:

//沒收到給用戶消費(fèi)通知,先判斷這個(gè)orderId時(shí)候已經(jīng)有加過積分的歷史記錄,如果沒有操作過,則增加。如果已經(jīng)操作過,直接返回不做任何處理。
List<UserPointHistory> lists = userPointDao.queryHistory(orderId);
if(CollectionUtils.isNotEmpty(lists)){
    //1.加100分。
    userPoint.add(pointCount,orderId);
    //2.保存增加記錄
      userPoint.addHistory(orderId);
}else{
    log.info("該訂單已經(jīng)操作過積分操作")
    return null;
}

Tip:如果冪等還不明白可以看我寫的《談?wù)勗趺蠢斫饨涌趦绲仍O(shè)計(jì),項(xiàng)目中如何保證接口冪等》,上面的代碼加積分和保存增加記錄要保證事務(wù)性,如果你不知道ACID千萬別給自己挖坑,被面試官逮住ACID一頓問。

面試官:這個(gè)問題相對不難,有解決思路問題就不大了。

2、面試官:

在多集群消息架構(gòu)中,如果消費(fèi)端要求接收到的消息是有序的,怎么解決消息順序消費(fèi)問題?

問題分析:這個(gè)問題什么意思呢,比如一個(gè)消息Producer發(fā)送順序是1 2 3,那Consumer接收到的消息也是 1 2 3 ,這就比較為難工程師了,但是還是有辦法的,想要實(shí)現(xiàn)消息有序就要犧牲點(diǎn)什么東西 ---- 性能/可靠性。

答:這個(gè)問題從三個(gè)角度考慮:

Producer:讓生產(chǎn)端同步發(fā)送消息,消息1確定發(fā)送成功后再發(fā)送消息2,不能異步,保證消息順序入隊(duì)。

服務(wù)端:Producer -> MQ Server -> Consumer 一對一關(guān)系,一對一服務(wù),這肯定能保證消息是按照順序消費(fèi)的,那么問題來了:

  • Producer -> MQ Server -> Consumer任意一個(gè)環(huán)節(jié)出現(xiàn)問題,那肯定整個(gè)鏈路都阻塞了。
  • 單通道模型性能成為瓶頸。

topic不分區(qū):意思就是讓同一個(gè)topic主題都入一個(gè)隊(duì)列,在分布式環(huán)境下如果同一個(gè)topic進(jìn)入多個(gè)分區(qū),那多個(gè)分區(qū)之間肯定無法保證消息順序了。

Consumer:保證消費(fèi)端是串行消費(fèi),禁止使用多線程。

但是這些方法都會(huì)犧牲掉系統(tǒng)的性能和穩(wěn)定性,順序性問題非要使用MQ來做,那也沒有太好的辦法了。

3、面試官:

那如何做到topic不分區(qū),能舉例說明一下嗎?

問題分析:說真的,工作中要求消息順序消費(fèi)的業(yè)務(wù)場景真的挺少見的,用到的時(shí)候少,你可以不用深入研究這一塊,知道方法就行,到時(shí)候真的遇到了知道從哪個(gè)方向下手。

答:用當(dāng)前比較流行的RocketMQ和Kafka舉例。

RocketMQ:RocketMQ提供了MessageQueueSelector隊(duì)列選擇機(jī)制,我們可以把 Topic 用Hash取模法,相同Topic的Hash值肯定是一樣的,讓同一個(gè) Topic 同一個(gè)隊(duì)列中,再使用同步發(fā)送,這樣就能保證消息在一個(gè)分區(qū)有序了。

Kafka: Kafka可以把 max.in.flight.requests.per.connection 參數(shù)設(shè)置成1,這樣就可以保證同一個(gè)topic在同一個(gè)分區(qū)內(nèi)了。

Tip:Topic就是一個(gè)字符串,給同一類消息取個(gè)名字加以區(qū)分,如:topic.com.xxx.order.orderId,大多數(shù)用戶都可以通過message key來定義,因?yàn)橥粋€(gè)key的message可以保證只發(fā)送到同一個(gè)partition,比如說key是user id,table row id等等。

總結(jié)

關(guān)于消息重復(fù)和消息順序消費(fèi)問題解決思路比較簡單,都是一些小技巧,雖然內(nèi)容比較枯燥,但是我已經(jīng)盡力說得通俗易懂。

如果用兩句話概括這一接的內(nèi)容:

如何保證消息重復(fù)問題:消費(fèi)端接口冪等。如何保證消息順序消費(fèi)問題:讓同一個(gè)消息不分區(qū),且單線程。

當(dāng)然面試的時(shí)候你可別這么干巴巴兩句話,那顯得你太沒水平了,面試最理想的效果就是無論多簡單的問題你都能滔滔不絕,讓面試官無話可說。

以上就是分布式面試消息隊(duì)列解決消息重復(fù)保證消息順序的詳細(xì)內(nèi)容,更多關(guān)于消息隊(duì)列解決消息重復(fù)保證消息順序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談java的接口和C++虛類的相同和不同之處

    淺談java的接口和C++虛類的相同和不同之處

    下面小編就為大家?guī)硪黄獪\談java的接口和C++虛類的相同和不同之處。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,祝大家游戲愉快哦
    2016-12-12
  • java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性

    java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性

    這篇文章主要介紹了java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot實(shí)現(xiàn)第一次啟動(dòng)時(shí)自動(dòng)初始化數(shù)據(jù)庫的方法

    SpringBoot實(shí)現(xiàn)第一次啟動(dòng)時(shí)自動(dòng)初始化數(shù)據(jù)庫的方法

    本文主要介紹了SpringBoot實(shí)現(xiàn)第一次啟動(dòng)時(shí)自動(dòng)初始化數(shù)據(jù)庫的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Spring-Retry的使用詳解

    Spring-Retry的使用詳解

    在日常的一些場景中, 很多需要進(jìn)行重試的操作.而spring-retry是spring提供的一個(gè)基于spring的重試框架,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-11-11
  • SpringCloud Gateway 利用 Mysql 實(shí)現(xiàn)動(dòng)態(tài)路由的方法

    SpringCloud Gateway 利用 Mysql 實(shí)現(xiàn)動(dòng)態(tài)路由的方法

    這篇文章主要介紹了SpringCloud Gateway 利用 Mysql 實(shí)現(xiàn)動(dòng)態(tài)路由的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 將idea中xml文件背景顏色去除的圖文教程

    將idea中xml文件背景顏色去除的圖文教程

    這篇文章主要介紹了將idea中xml文件背景顏色去除,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java設(shè)計(jì)模式之觀察者模式解析

    Java設(shè)計(jì)模式之觀察者模式解析

    這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式解析,觀察者模式,又被稱為發(fā)布/訂閱模式,它定義了一種一對多的依賴關(guān)系,讓多個(gè)觀察者對象同時(shí)監(jiān)聽某一個(gè)主題對象,這個(gè)主題對象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對象,使他們能夠自動(dòng)更新自己,需要的朋友可以參考下
    2023-09-09
  • 基于Java實(shí)現(xiàn)掃碼登錄的示例代碼

    基于Java實(shí)現(xiàn)掃碼登錄的示例代碼

    相信大家對二維碼都不陌生,生活中到處充斥著掃碼登錄的場景,如登錄網(wǎng)頁版微信、支付寶等。本文將利用Java實(shí)現(xiàn)一個(gè)簡易版掃碼登錄的 Demo,需要的可以參考一下
    2022-04-04
  • Java編寫Mapreduce程序過程淺析

    Java編寫Mapreduce程序過程淺析

    MapReduce是一種用于處理大規(guī)模數(shù)據(jù)集的并行編程模型,其特點(diǎn)高效性和可擴(kuò)展性,在本文中,我們將深入了解MapReduce,并使用Java編寫一個(gè)簡單的MapReduce程序,需要的朋友可以參考下
    2023-05-05
  • 詳解MyBatis的SqlSession獲取流程

    詳解MyBatis的SqlSession獲取流程

    SqlSession的獲取是通過SqlSessionFactory的openSession() 方法,那么具體的獲取流程是什么,所以本文就給大家詳細(xì)講解一下MyBatis的SqlSession獲取流程,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

铜山县| 松江区| 闽侯县| 长岭县| 绥棱县| 英德市| 博客| 鹤壁市| 广南县| 开原市| 中方县| 广饶县| 桓仁| 抚顺市| 含山县| 同德县| 汉中市| 娄烦县| 土默特左旗| 施甸县| 柏乡县| 黔南| 常州市| 永济市| 鹿邑县| 阿拉善盟| 如东县| 灵石县| 尼玛县| 南雄市| 景谷| 凤凰县| 二手房| 台南县| 松原市| 会理县| 满洲里市| 丰原市| 洛宁县| 隆尧县| 沁源县|