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