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