RabbitMQ使用過程中,有些業(yè)務(wù)場景需要我們保證順序消費(fèi),例如:業(yè)務(wù)上產(chǎn)生三條消息,分別是對數(shù)據(jù)的增加、修改、刪除操作,如果沒有保證順序消費(fèi),執(zhí)行順序可能變成刪除、修改、增加,這就亂了 。
RabbitMQ的消息順序問題,需要分三個環(huán)節(jié)看待,發(fā)送消息的順序、隊列中消息的順序、消費(fèi)消息的順序。
發(fā)送消息的順序先看一下是什么原因造成了發(fā)送消息時候的順序錯亂
發(fā)送消息的順序性,一般來說不做要求,但是如果一定要求順序,可以使用鎖機(jī)制配合 ack機(jī)制 來保證消息的順序到達(dá)
隊列中消息的順序消息隊列中的消息是遵循FIFO(先進(jìn)先出)原則,天然有序
消費(fèi)消息的順序有這樣一個訂單操作,insert 、update、delete連續(xù)操作,并且消息已經(jīng)順序存在queue中,那么如何保證消費(fèi)順序是insert 、update、delete,而不是delete、insert 、update呢?
方案一:拆分多個queue,每個queue一個consumer,該條訂單的相關(guān)操作全部放到這個queue中,由這一個consumer消費(fèi),這樣做多了一些queue。
方案二:就一個queue但是對應(yīng)一個consumer,然后這個consumer內(nèi)部用內(nèi)存隊列做排隊,該條訂單相關(guān)的消息全部放到一個隊列中,然后分發(fā)給底層不同的worker線程來處理
可靠性實際上消息隊列是沒法百分百保證不丟失的,我們只能盡量降低概率,然后在消息丟失后記錄日志,再處理
有這樣一個典型的訂單場景
要解決上述問題,就是要保證消息一定要可靠地被消費(fèi),那么我們可以來分析下消息有哪些步驟會出問題
RabbitMQ 發(fā)送的消息是這樣的 , 消息被生產(chǎn)者發(fā)到指定的交換機(jī)根據(jù)路由規(guī)則路由到綁定的隊列,然后推送給消費(fèi)者 。
在這個過程中,可能會出一下問題
下面是單消費(fèi)實例的解決方案
多實例的先留個坑,以后再填
生產(chǎn)者弄丟消息RabbitMQ 提供了確認(rèn)和回退機(jī)制,有一個異步監(jiān)聽機(jī)制,每次發(fā)送消息,如果成功/未成功發(fā)送到交換機(jī)都可以觸發(fā)一個監(jiān)聽ConfirmCallback(),從交換機(jī)路由到隊列失敗也會有一個監(jiān)聽ReturnsCallback()。只需要開啟這兩個監(jiān)聽機(jī)制,使用記錄日志、發(fā)送郵件通知、落庫定時任務(wù)掃描重發(fā)這些應(yīng)對策略
生產(chǎn)者弄丟數(shù)據(jù)其實及其罕見,落庫定時任務(wù)掃描重發(fā)工作量大,一般記錄日志后,發(fā)郵件給對應(yīng)人員,補(bǔ)充數(shù)據(jù)庫數(shù)據(jù)即可
RabbitMQ弄丟消息宕機(jī)重啟不開啟持久化的情況下 RabbitMQ 重啟之后所有隊列和消息都會消失,所以我們創(chuàng)建隊列時設(shè)置持久化
消費(fèi)者弄丟消息RabbitMQ 給我們提供了消費(fèi)者應(yīng)答(ack)機(jī)制,默認(rèn)情況下這個機(jī)制是自動應(yīng)答,只要消息推送到消費(fèi)者就會自動 ack ,然后 RabbitMQ 刪除隊列中的消息。啟用手動應(yīng)答之后我們在消費(fèi)端調(diào)用 API 手動 ack 確認(rèn)之后,RabbitMQ 才會從隊列刪除這條消息 。
開啟手動ack,在業(yè)務(wù)處理完成之后手動ack即可,如果在業(yè)務(wù)處理過程中出異常了,隊列會給消費(fèi)者重推,也要注意重推導(dǎo)致的循環(huán)異常,可以配置重試次數(shù)策略。
消息重復(fù)消費(fèi)(冪等性)這個也是生產(chǎn)環(huán)境業(yè)務(wù)中經(jīng)常出現(xiàn)的場景,重復(fù)消費(fèi)也要從兩方面分析,為什么會出現(xiàn)重復(fù)消費(fèi)
生產(chǎn)時消息重復(fù)在網(wǎng)絡(luò)波動的情況下,生產(chǎn)者給MQ服務(wù)器發(fā)送消息,由于網(wǎng)絡(luò)原因?qū)е律a(chǎn)者沒有收到ACK確認(rèn)消息,但是MQ服務(wù)器實際上已經(jīng)接收到了消息,在這種情況下生產(chǎn)者就會重新發(fā)送一遍剛才的消息。
此時重發(fā)是MQ-client發(fā)起的,消息的處理是MQ-server,為了避免broker落地重復(fù)的消息,對每條消息,MQ系統(tǒng)內(nèi)部必須生成一個inner-msg-id,作為去重和冪等的依據(jù),這個內(nèi)部消息ID的特性是:
有了這個inner-msg-id,就能保證即使重發(fā),也只有1條消息落到MQ-server的DB中
消費(fèi)時消息重復(fù)在消費(fèi)者方面如果出現(xiàn)網(wǎng)絡(luò)問題,比如消費(fèi)者對消息已經(jīng)成功消費(fèi)了,在向MQ服務(wù)器進(jìn)行確認(rèn)的時候網(wǎng)絡(luò)異常了,這時候MQ服務(wù)器就沒有接收到確認(rèn),MQ為了保證消息被消費(fèi),就會繼續(xù)向消費(fèi)者發(fā)送之前已經(jīng)被消費(fèi)了的消息,這種情況下消費(fèi)者就會接收到兩條一樣的消息。
我們解決消息重復(fù)消費(fèi)主要是保證消費(fèi)的冪等性,有兩種角度,第一種就是不讓消費(fèi)端執(zhí)行兩次,第二種是讓它重復(fù)消費(fèi)了,但是不會對我的業(yè)務(wù)數(shù)據(jù)造成影響就行。通常可以在發(fā)消息的時候攜帶業(yè)務(wù)唯一id,消費(fèi)成功后保存到redis/db中,消費(fèi)前再檢查下有沒有這個ID,有的話就表示已經(jīng)消費(fèi)過了,或者使用數(shù)據(jù)庫唯一性主鍵約束,再或者使用cas,最后遇到重復(fù)消息丟棄消息即可
消息堆積你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
文章標(biāo)題:RabbitMQ順序性、可靠性、重復(fù)消費(fèi)、消息堆積解決方案-創(chuàng)新互聯(lián)
URL標(biāo)題:http://bm7419.com/article34/ddhppe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、營銷型網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、微信公眾號、小程序開發(fā)、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容