消息可能丢失的场合:
1)消息从生产者写入到消息队列的过程;针对这种情况,我建议你采用的方案是消息重传。也就是当你发现发送超时后就将消息重新发一次,但不能无限制地重传消息。一般来说,如果不是消息队列发生故障或者是到消息队列的网络断开了,重试 2~3 次就可以了。
2)消息在消息队列中的存储场景;可以考虑以集群方式部署 Kafka 服务,通过部署多个副本备份数据保证消息尽量不丢失。建议是:
1. 如果你需要确保消息一条都不能丢失,那么建议不要开启消息队列的同步刷盘,而是用集群的方式来解决,可以配置当所有 ISR Follower 都接收到消息才返回成功。
2. 如果对消息的丢失有一定的容忍度,那么建议不部署集群,即使以集群方式部署,也建议配置只发送给一个 Follower 就可以返回成功了。
3. 我们的业务系统一般对于消息的丢失有一定的容忍度,比如说以上面的红包系统为例,如果红包消息丢失了,我们只要后续给没有发送红包的用户补发红包就好了。
3)消息被消费者消费的过程。一定要等到消息接收和处理完成后才能更新消费进度,但是这也会造成消息重复的问题,比方说某一条消息在处理之后消费者恰好宕机了,那么因为没有更新消费进度,所以当这个消费者重启之后还会重复地消费这条消息。
此文章为5月Day22学习笔记,内容来源于极客时间《高并发系统设计 40 问》