造成重复消费的原因:
MQ向消费者推送message,消费者向MQ返回ack,告知所推送的消息消费成功。但是由于网络波动等原因,可能造成消费者向MQ返回的ack丢失。MQ长时间(一分钟)收不到ack,于是会向消费者再次推送该条message,这样就造成了重复消费。
解决重复消费的办法:
用从存储(redis或者mysql)记录一下已经消费的message的id,当message被消费前先去存储中查一下消费记录,没有该条message的id则正常消费返回ack,有该条message的id的话不用消费直接返回ack给MQ。
当然实际生产中的话选用redis是比较好的选择,毕竟查mysql要进行磁盘IO,效率要低得多,而且绝大多数重复消费都是由于MQ没有收到消费者的ack于是造成MQ再次向消费者进行同一条message的投递。所以message的消费记录其实我们并不需要一直记录,只需要保存一段时间,当下次投递过来的时候消费者能查到消费记录然后准确返回ack给MQ就行。
以下是一个使用redis解决重复消费的示例步骤:
- 监听器接收MQ队列中的数据。
- 利用redis的setnx命令,以消息唯一id为key,以消息内容为value,超时时间设置为10分钟,存入redis中。
- 如果能够成功存入,说明没有重复消费,则处理业务,处理完业务后返回ack或者nack确认。
- 如果存不进去,则说明重复消费,直接返回ack确认的回调信息就可以了。
版权归原作者 _BugMan 所有, 如有侵权,请联系我们删除。