RabbitMQ消息丢失、积压、重复等解决方案
消息丟失
1、只要訂單完成我們就會(huì)發(fā)送一條消息給MQ,這個(gè)途中突然MQ服務(wù)器網(wǎng)絡(luò)中斷,導(dǎo)致消息無(wú)法抵達(dá)
做好容錯(cuò)方法需要在消息發(fā)送前加上異常處理
try {
rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);
}
catch (Exception e) {
//將沒法送成功的消息進(jìn)行重試發(fā)送
}
還可以將消息存入數(shù)據(jù)庫(kù),把失敗的消息定期重新再發(fā)一遍
2、當(dāng)消息發(fā)送給MQ,通過Brock通過交換機(jī)抵達(dá)隊(duì)列,MQ關(guān)機(jī)了,只有抵達(dá)隊(duì)列才能實(shí)現(xiàn)消息持久化
這時(shí)候需要使用生產(chǎn)者的確認(rèn)機(jī)制
只要消息收到了會(huì)自動(dòng)持久化,如果進(jìn)入另一個(gè)回調(diào)方法說(shuō)明報(bào)錯(cuò)了,需要修改數(shù)據(jù)庫(kù)使消息重發(fā)
3、自動(dòng)ACK的狀態(tài)下。消費(fèi)者收到消息,但沒來(lái)得及消息然后宕機(jī)
一定開啟手動(dòng)ACK,消費(fèi)成功才移除,失敗或者沒來(lái)得及處理就noAck并重新入隊(duì)
消息重復(fù)
1、消息消費(fèi)成功,事務(wù)已經(jīng)提交,ack時(shí),機(jī)器宕機(jī)。導(dǎo)致沒有ack成功,Broker的消息重新由unack變?yōu)閞eady,并發(fā)送給其他消費(fèi)者
在ack的時(shí)候宕機(jī),導(dǎo)致消息沒有確認(rèn),又需要重新發(fā)送
2、消息消費(fèi)失敗,由于重試機(jī)制,自動(dòng)又將消息發(fā)送出去
關(guān)閉訂單的時(shí)候,沒有成功,又重新進(jìn)入隊(duì)列再次執(zhí)行,這種是可以允許的
解決辦法:
消費(fèi)者的業(yè)務(wù)消費(fèi)接口應(yīng)該設(shè)計(jì)為冪等性的。比如扣庫(kù)存有工作單的狀態(tài)標(biāo)志
使用防重表(redis/mysql),發(fā)送消息每一個(gè)都有業(yè)務(wù)的唯一標(biāo)識(shí),處理過就不用處理
rabbitMQ的每一個(gè)消息都有redelivered字段,可以獲取是否是被重新投遞過來(lái)的,而不是第一次投遞過來(lái)的
判斷當(dāng)前消息是否是第二次及以后被派發(fā)過來(lái)的
消息積壓
消費(fèi)者宕機(jī)積壓
消費(fèi)者消費(fèi)能力不足積壓
發(fā)送者發(fā)送流量太大
上線更多的消費(fèi)者,進(jìn)行正常消費(fèi)
上線專門的隊(duì)列消費(fèi)服務(wù),將消息先批量取出來(lái),記錄數(shù)據(jù)庫(kù),離線慢慢處理
這也是實(shí)現(xiàn)了柔性事務(wù)-可靠消息+最終一致性解決方案
做好消息確認(rèn)機(jī)制(生產(chǎn)者、消費(fèi)者)+手動(dòng)確認(rèn)機(jī)制
并把消息在數(shù)據(jù)庫(kù)做好記錄
總結(jié)
以上是生活随笔為你收集整理的RabbitMQ消息丢失、积压、重复等解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Import注解
- 下一篇: 怎样理解人生观、价值观、世界观?