rabbitmq消息丟失的三種情況
- 生產者將消息發送到RabbitMQ的過程中時,消息丟失。
- 消息發送到RabbitMQ,還未被持久化就丟失了數據。
- 消費者接收到消息,還未處理,比如服務宕機導致消息丟失。
解決方案
生產者發送過程中,消息丟失
方案1 - 開啟RabbitMQ事務
生產者發送消息之前,開啟RabbitMQ事務channel.txSelect,如果消息沒有成功被RabbitMQ接收到,那么生產者會收到異常報錯,此時可以回滾事務channel.txRollback,然后重試發送消息,如果收到了消息,那么可以正常提交事務。channel.txCommit。(不建議,同步阻塞)
方案2 - 使用confirm機制
事務機制和Confirm機制最大的不同在于,事務機制是同步的,提交一個事務之后會阻塞在那兒,但是Confirm機制是異步的。
在生產者開啟confirm機制后,每次寫消息都會分配一個唯一id,然后RabbitMQ正常處理了這個消息,RabbitMQ會回傳給你一個ack消息,告訴你這個消息發送ok了,如果沒能正常處理,會回調一個nack接口,告訴你這個消息失敗了,此時,你可以對這個消息發起重試。
并且你可以基于這個機制,維護每個消息的id,如果超過一定的時候還沒接收到這個消息的回調,你可以進行重發。(消費者需要做好冪等)
RabbitMQ 服務端消息丟失
丟失場景:
- 未持久化消息
- 磁盤損壞或集群故障
方案 - 消息持久化
RabbitMQ的消息默認存放在內存上的,如果不特別聲明設置,消息不會持久化保存到硬盤上,如果節點重啟或者意外crash掉,消息就會丟失。
Exchange 設置持久化
Queue 設置持久化
Message 設置持久化
方案 - 設置集群鏡像模式
RabbitMQ有以下三種部署模式
- 單節點部署
最簡單的模式,非集群模式,節點掛了,業務癱瘓 - 普通模式(默認集群模式)
消息只會存在主節點上,不會同步到其他節點,當前節點宕機,有影響的業務會癱瘓,只能等待節點重啟后恢復可用, - 鏡像模式(鏡像隊列模式)
消息會同步到其他節點上,可以設置同步的節點個數,但吞吐量會下降,屬于RabbitMQ的HA方案
以下是三種HA策略模式
- 同步所有的
- 同步最多N個機器的
- 只同步至服務執行名稱的節點
消費者丟失消息
方案 - ACK確認機制
關閉自動應答(自動ack),業務服務端在確保正確處理完消息后,手動ack,避免消息還未被處理完就ack,這樣就避免了,當一個消費者出了問題,也會有其他的消費者去消費, 保證了消息不丟失的場景。