MQ幂等性方案
什么是消息幂等
当出现消费者对某条消息重复消费的情况时,重复消费的结果与消费一次的结果是相同的,并且多次消费并未对业务系统产生任何负面影响,那么这个消费者的处理过程就是幂等的。
适用场景
在互联网应用中,尤其在网络不稳定的情况下,MQ的消息有可能会出现重复。如果消息重复会影响业务处理,则需要对消息做幂等处理。
消息重复的场景如下:
发送时消息重复
当一条消息已被成功发送到服务端并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端应答失败。 如果此时生产者意识到消息发送失败并尝试再次发送消息,消费者后续会收到两条内容相同但Message ID不同的消息。
投递时消息重复
消息消费的场景下,消息已投递到消费者并完成业务处理,当客户端给服务端反馈应答的时候网络闪断。为了保证消息至少被消费一次,消息队列RocketMQ版的服务端将在网络恢复后再次尝试投递之前已被处理过的消息,消费者后续会收到两条内容相同并且Message ID也相同的消息。
负载均衡时消息重复(包括但不限于网络抖动、Broker重启以及消费者应用重启)
当消息队列RocketMQ版的Broker或客户端重启、扩容或缩容时,会触发Rebalance,此时消费者可能会收到少量重复消息。
处理方法
业务操作之前进行状态查询
消费端开始执行业务操作时,通过幂等id首先进行业务状态的查询,如状态已为最终状态(如已出库/已取消),则直接ack
乐观锁
每个数据都有一个版本号,和当前版本号相同时进行更新操作
去重表(缓存)
唯一索引,如果已存在值,就不进行更新了
来源: