一、前言
首先,rabbitMQ并没有为消息的重复消费而设计一种解决方法,这个解决方法需要我们来根据业务自己实现,我整理了几种常见的解决方法。
二、消息重复发送导致消息被重复消费的场景
第一个场景,在生产者发送消息给rabbitMQ服务器的时候,有可能因为网络波动等情况,导致生产者收不到rabbitMQ服务器的应答,导致生产者再发送一条消息。
第二个场景,也是因为网络波动等问题,导致rabbitMQ服务器在向消费者发送消息的时候,没有收到消费者的应答,重复向消费者发生消息。
这两个场景,其实最终都是导致消费者重复消费多次消息,所以在一般的场景下,我们只需要在消费者那里做消息重复消费的保障即可。
三、解决方法
使用数据库一个表来记录消息的状态(或者用redis来记录也可以)。每次消费之前,都查询判断消息的状态,是否已经被消费了。这个状态可以是id。例如,如果消息是订单,而且id是全局唯一的,那么只需要拿这个订单id来做判断即可。
四、总结
总的来说,就是要保证消费者的幂等性。
幂等性,指的是多次调用接口,结果是一致的。例如,订单接口,不能因为用户多次点击提交订单而创建多张订单,支付接口,同一张订单不能多次支付等等。
如何保证幂等性?
① 使用代码的逻辑判断,就像上述的解决方法一样,判断消息状态是否已经被消费过了
② 使用token,要申请,一次有效性。
例如,在创建订单的场景下。首先,先生成一个token,返回给客户端存起来,同时也在后端存起来(redis)。当他创建订单的时候,带着这个token来请求后端,后端判断redis里是否存在,如果存在,则操作成功,同时删除token(删除了之后,就算他重复多次调用,前边的判断不成立,这样子就不能多次操作了)。
参考链接: