MQ如何保證消息不丟失
- 問題分析
- 具體分析及解決方案
- RabbitMQ
- 生產者
- RabbitMQ配置
- 消費者
- Kafka
- Kafka配置
- 消費者
問題分析
從Kafka和RabbitMQ進行分析,MQ消息丟失的情況有生產者推送消息時數據丟失,MQ中間件宕機情況下數據丟失,消費者消費時消息丟失。
- 問題延伸:如何保證MQ消息的順序性,如何保證不重復消費
具體分析及解決方案
RabbitMQ的情況下,消息不存在queue里面,queue的數據時存在內存當中的,不一定會被持久化,當中間件重啟后,數據會丟失。消費者默認自動是ack確認機制,不關注數據是否持久化完成。
RabbitMQ
生產者
- 可以使用其自帶的事務機制,在生產者在推送數據時開啟事務,但是這是串行化執行,會影響其他事務的執行;
channel.txSelect
try{
}
catch(){channel.rollback
}
channel.commit
- 可以使用comfirm機制,當消息被RabbitMQ接收了,會給生產者發送ask,否則發送回調noack方法。保證消息不丟失,也保證了生產者的高效性。異步執行
RabbitMQ配置
對于經典隊列,將durable屬性設置為true,開啟queue隊列的持久化
對于消息的持久化,保證RabbitMQ在收到消息及時落盤,發送消息時將deliveryMode屬性設置為2
設置完后,在RabbitMQ重啟后,會恢復Queue里面和Message消息
消費者
關閉自動提交ack機制,在消費者消費完成后手動提交ack
Kafka
Kafka配置
- 這種情況下必須保證每個分區都要有兩個副本存在。設置replication.factor大于1
- 設置min.insync.replicas大于1,保證每個leader必須有一個follower跟自己保持聯系
- 將akcs設置為all,即acks=all,要求每條數據必須寫入所有replica,及寫入到所有的副本,在leader掛了之后follower通過選舉之后成為新的leader可以它的數據可以被消費。
消費者
關閉自動提交offset機制,手動提交offset