什么是幂等性
幂等性:是数学和计算机科学中某些运算的性质, 它们可以被多次应⽤, ⽽不会改变初始应⽤的结果。
在消息队列中,幂等性指的是,同一条消息即使被消费者获取了多次,但实际只执行了一次消费。例如:对于一条支付消息,可能被消费者获取了多次,但最终只进行了一次扣费操作。
因此,消息队列如何保证幂等性,消息队列如何保证消息不会被重复消费,本质上都是同一个问题。
为什么会产生幂等性的问题
在实际中,对于可靠性要求比较高的场景,往往会使用确认应答的方式。但这些应答可能会在传输的过程中丢失(网络,客户端异常等),此时就回触发重发。导致一条消费被获取多次。
消息队列本身是无法保证消息只被恰好消费一次!只能保证消息被消费最多被消费一次或者最少被消费一次!
大致可以分为两个情况:
1. Producer发送消息给Broker,使用发布确认的模式,当Producer发送一条消息给Broker,此时Broker还需要发送一条ACK给Producer,如果此时ACK丢了,Producer这边并不知道,会进行重发一条一模一样的消息,这就导致了同一条消息发送多次,Consumer如果不进行处理就会消费多次。
2. Broker将消息推送给Consumer,使用手动应答的模式,当Broker推送一条消息给Consumer,此时Consumer需要发送一条ACK给Broker,如果此时ACK丢了, Consumer这边也无法知道,就会重发一条一样的消息,最终导致一条消息被重复消费。
解决方案
核心思路是:校验消息的唯一性
1.为每条消息分配一个全局唯一ID,消费者使用容器存储这个ID集合,后续消费者获取到一条消息,首先判断这条消息ID是否已经在ID集合了,如果不存在就消费消息,并将消息的唯一ID储存在集合中,如果存在就不消费。
2.通过查询数据库等持久层,查看消费记录是否已经存在过,如果存在就不进行消费。