保证消息队列的不重复消费,意思就是要保证数据的幂等性
那么我们就要了解消息队列为什么会被重复消费呢?
队列中的消息有一个offset的概念,简单来说就是一条消息的顺序id。每条消息都会有一个自己的offset,当这条消息被消费时,消费者会定时告诉中间件,说我当前消费到哪条数据了。如图:
这时候呢,如果消费者突然宕机了,那下次启动的时候肯定要告诉kafka说我消费到哪个了,你就接着给我推送吧。那下次直接推送offset=104的数据就可以了
但是,消费者的这个这个回执并不是实时发送的,而是定期发送的。如果offset=103的这条数据消费完了,还没告诉kafka。那下次kafka就接着102推送,就会造成消息重复消费。当然,这只是举了一个最简单的例子,真正生产中的情况比这复杂得多,都是有可能造成重复消息。
如何保证幂等性
按照业务的需求,如果是radis的话肯定没有关系啊,redis的set集合会自动去重;
那么如果是数据库呢,我们可以再消息中加一个主键,用数据库主键的唯一性来保证消息的幂等。
还有其他方式比如说将offset在程序中做一个缓存之类的,按照自己的个性化业务做不同的幂等排重。