大家设想下面一个场景:
消费者在消费完一条消息后,向 RabbitMQ 发送一个 ack 确认,此时由于网络断开或者其他原因 导致 RabbitMQ 并没有收到这个 ack,那么此时 RabbitMQ 并不会将该条消息删除,当重新建立 起连接后,消费者还是会再次收到该条消息,这就造成了消息的重复消费。同时,由于类似的原因,消息在发送的时候,同一条消息也可能会发送两次。种种原因导致我们在消费消息时,一定要处理好幂等性问题。
幂等性处理也不是很难,基本上都是从业务逻辑上面处理,我来讲述一下大致的思路。
首先我们采用Redis,在消费者消费消息之前,先将消息的id放到Redis中,储存方式如下:
key | value | status |
id | 0 | 正在执行业务 |
id | 1 | 业务执行成功 |
如果 ack 失败,在 RabbitMQ 将消息交给其他的消费者时,先执行 setnx,如果 key 已经存在,则证明此前有人消费过该消息,获取他的值,如果是 0,当前消费者就什么都不做,如果是 1,直接 ack 即可。
代码如下:
首先需要打开redi