如何保證消息不被重復消費?或者說歌豺,如何保證消息消費的冪等性推穷?

面試官心理分析

其實這是很常見的一個問題,這倆問題基本可以連起來問世曾。既然是消費消息缨恒,那肯定要考慮會不會重復消費?能不能避免重復消費轮听?或者重復消費了也別造成系統(tǒng)異称叮可以嗎?這個是 MQ 領域的基本問題血巍,其實本質上還是問你使用消息隊列如何保證冪等性萧锉,這個是你架構里要考慮的一個問題。


面試題剖析

回答這個問題述寡,首先你別聽到重復消息這個事兒柿隙,就一無所知吧,你先大概說一說可能會有哪些重復消費的問題鲫凶。

首先禀崖,比如 RabbitMQ、RocketMQ螟炫、Kafka波附,都有可能會出現(xiàn)消息重復消費的問題,正常。因為這問題通常不是 MQ 自己保證的掸屡,是由我們開發(fā)來保證的封寞。挑一個 Kafka 來舉個例子,說說怎么重復消費吧仅财。

Kafka 實際上有個 offset 的概念狈究,就是每個消息寫進去,都有一個 offset盏求,代表消息的序號抖锥,然后consumer 消費了數(shù)據(jù)之后,每隔一段時間(定時定期)碎罚,會把自己消費過的消息的 offset 提交一下宁改,表示“我已經消費過了,下次我要是重啟啥的魂莫,你就讓我繼續(xù)從上次消費到的 offset 來繼續(xù)消費吧”还蹲。

但是凡事總有意外,比如我們之前生產經常遇到的耙考,就是你有時候重啟系統(tǒng)谜喊,看你怎么重啟了,如果碰到點著急的倦始,直接 kill 進程了斗遏,再重啟。這會導致 consumer 有些消息處理了鞋邑,但是沒來得及提交 offset诵次,尷尬了。重啟之后枚碗,少數(shù)消息會再次消費一次逾一。

舉個栗子。

有這么個場景肮雨。數(shù)據(jù) 1/2/3 依次進入 kafka遵堵,kafka 會給這三條數(shù)據(jù)每條分配一個 offset,代表這條數(shù)據(jù)的序號怨规,我們就假設分配的 offset 依次是 152/153/154陌宿。消費者從 kafka 去消費的時候,也是按照這個順序去消費波丰。假如當消費者消費了 offset=153 的這條數(shù)據(jù)壳坪,剛準備去提交 offset 到 zookeeper,此時消費者進程被重啟了掰烟。那么此時消費過的數(shù)據(jù) 1/2 的 offset 并沒有提交爽蝴,kafka 也就不知道你已經消費了 offset=153 這條數(shù)據(jù)扩灯。那么重啟之后,消費者會找 kafka 說霜瘪,嘿,哥兒們惧磺,你給我接著把上次我消費到的那個地方后面的數(shù)據(jù)繼續(xù)給我傳遞過來颖对。由于之前的 offset 沒有提交成功,那么數(shù)據(jù) 1/2 會再次傳過來磨隘,如果此時消費者沒有去重的話缤底,那么就會導致重復消費。

如果消費者干的事兒是拿一條數(shù)據(jù)就往數(shù)據(jù)庫里寫一條番捂,會導致說个唧,你可能就把數(shù)據(jù) 1/2 在數(shù)據(jù)庫里插入了 2 次,那么數(shù)據(jù)就錯啦设预。

其實重復消費不可怕徙歼,可怕的是你沒考慮到重復消費之后,怎么保證冪等性鳖枕。

舉個例子吧魄梯。假設你有個系統(tǒng),消費一條消息就往數(shù)據(jù)庫里插入一條數(shù)據(jù)宾符,要是你一個消息重復兩次酿秸,你不就插入了兩條,這數(shù)據(jù)不就錯了魏烫?但是你要是消費到第二次的時候辣苏,自己判斷一下是否已經消費過了,若是就直接扔了哄褒,這樣不就保留了一條數(shù)據(jù)稀蟋,從而保證了數(shù)據(jù)的正確性。

一條數(shù)據(jù)重復出現(xiàn)兩次呐赡,數(shù)據(jù)庫里就只有一條數(shù)據(jù)糊治,這就保證了系統(tǒng)的冪等性。

冪等性罚舱,通俗點說井辜,就一個數(shù)據(jù),或者一個請求管闷,給你重復來多次粥脚,你得確保對應的數(shù)據(jù)是不會改變的,不能出錯包个。

所以第二個問題來了刷允,怎么保證消息隊列消費的冪等性冤留?

其實還是得結合業(yè)務來思考,我這里給幾個思路:

????????????比如你拿個數(shù)據(jù)要寫庫树灶,你先根據(jù)主鍵查一下纤怒,如果這數(shù)據(jù)都有了,你就別插入了天通,update 一下好吧泊窘。

? ? ? ? ? ? ?比如你是寫 Redis,那沒問題了像寒,反正每次都是 set烘豹,天然冪等性。

????????????比如你不是上面兩個場景诺祸,那做的稍微復雜一點携悯,你需要讓生產者發(fā)送每條數(shù)據(jù)的時候,里面加一個全局唯一的 id筷笨,類似訂單 id 之類的東西憔鬼,然后你這里消費到了之后,先根據(jù)這個 id 去比如Redis 里查一下胃夏,之前消費過嗎逊彭?如果沒有消費過,你就處理构订,然后這個 id 寫 Redis侮叮。如果消費過了,那你就別處理了悼瘾,保證別重復處理相同的消息即可囊榜。

比如基于數(shù)據(jù)庫的唯一鍵來保證重復數(shù)據(jù)不會重復插入多條。因為有唯一鍵約束了亥宿,重復數(shù)據(jù)插入只會報錯卸勺,不會導致數(shù)據(jù)庫中出現(xiàn)臟數(shù)據(jù)。

當然烫扼,如何保證 MQ 的消費是冪等性的曙求,需要結合具體的業(yè)務來看。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末映企,一起剝皮案震驚了整個濱河市悟狱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌堰氓,老刑警劉巖挤渐,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異双絮,居然都是意外死亡浴麻,警方通過查閱死者的電腦和手機得问,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來软免,“玉大人宫纬,你說我怎么就攤上這事「嘞簦” “怎么了漓骚?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長向抢。 經常有香客問我,道長胚委,這世上最難降的妖魔是什么挟鸠? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮亩冬,結果婚禮上艘希,老公的妹妹穿的比我還像新娘。我一直安慰自己硅急,他們只是感情好覆享,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著营袜,像睡著了一般撒顿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荚板,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天凤壁,我揣著相機與錄音,去河邊找鬼跪另。 笑死拧抖,一個胖子當著我的面吹牛,可吹牛的內容都是我干的免绿。 我是一名探鬼主播唧席,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嘲驾!你這毒婦竟也來了淌哟?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤辽故,失蹤者是張志新(化名)和其女友劉穎绞绒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榕暇,經...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蓬衡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年喻杈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狰晚。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡筒饰,死狀恐怖,靈堂內的尸體忽然破棺而出壁晒,到底是詐尸還是另有隱情瓷们,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布秒咐,位于F島的核電站谬晕,受9級特大地震影響,放射性物質發(fā)生泄漏携取。R本人自食惡果不足惜攒钳,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雷滋。 院中可真熱鬧不撑,春花似錦、人聲如沸晤斩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澳泵。三九已至实愚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兔辅,已是汗流浹背爆侣。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留幢妄,地道東北人兔仰。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蕉鸳,于是被迫代替她去往敵國和親乎赴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容