前言: 消息丢失问题,在此以rabbitMQ和kafka两种消息中间件进行分析解决,容我娓娓道来,此文章仅代表鄙人的总结和理解,如有错漏,欢迎指正...
首先不同的mq消息丢失的原因也不同:
rabbitMQ 丢失分析与解决
A:生产者弄丢了数据
生产者将数据发送到rabbitmq的时候,可能在传输过程中因为网络等问题而将数据弄丢了。
解决方案:
1.可以选择使用rabbitmq提供的事务功能(缺点:事务会导致阻塞,吞吐量下降)
2.可以开启confirm模式(confirm机制是异步的,推荐使用)
B:rabbitmq自己丢了数据
如果没有开启rabbitmq的持久化,那么rabbitmq一旦重启,那么数据就丢了。所依必须开启持久化将消息持久化到磁盘,这样就算rabbitmq挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢失。除非极其罕见的情况,rabbitmq还没来得及持久化自己就挂了,这样可能导致一部分数据丢失。
解决方案:
1.设置消息持久化到磁盘
C:消费端弄丢了数据
主要是因为消费者消费时,刚消费到,还没有处理,结果消费者就挂了,这样你重启之后,rabbitmq就认为你已经消费过了,然后就丢了数据。
解决方案:
使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack
kafka 丢失分析与解决
A:生产者弄丢了数据
生产者没有设置相应的策略,发送过程中丢失数据。
解决方案:
通过kafka设置了ack=all
B:kafka弄丢了数据
比较常见的一个场景,就是kafka的某个broker宕机了,然后重新选举partition的leader时。如果此时follower还没来得及同步数据,leader就挂了,然后某个follower成为了leader,他就少了一部分数据。
解决方案: 通过kafka的提供的一些合理配置,可以做到0丢失
C:消费者弄丢了数据
消费者消费到了这个数据,然后消费之自动提交了offset,让kafka知道你已经消费了这个消息,当你准备处理这个消息时,自己挂掉了,那么这条消息就丢了。
解决方案:
关闭自动提交offset,在自己处理完毕之后手动提交offset,这样就不会丢失数据。
参考博客:
关于MQ的几件小事(四)如何保证消息不丢失
更多相关【java开发消息中间件MQ篇】系列文章,请查阅我的个人博客哦...
结语:以往都是看别人的博客进行学习技术,其中不乏有精华博客也有吊儿郎当的CV大法文章,所以决定将自己所学所用所整理的知识分享给大家,主要还是想为了后浪们少走些弯路,多些正能量的博客,如有错漏,欢迎指正,仅希望大家能在我的博客中学到知识,解决到问题,那么就足够了。谢谢大家!(转载请注明原文出处)