小王来学习一波
2018-09-17 09:02
老师您好,如果消息提供方发送消息并且正常投递,但是消费方出现问题(网络链接出问题或者其他异常)这时候用补偿的方法会不会造成重复投递。怎么能很好的监控到消费方已经把消息正常的进行消费。
如果消息正常投递,消息进入队列,这时候生产者的任务已经完成,数据库也会更新为投递成功。
消费者出现问题,如果设置了消息正常消费后发送ack响应,那么这个消息队列不会收到ack响应,所以不会从队列中移除。当消费者和broker断开连接,该消息会重新变为ready状态,等待新的消费者消费。
上面说错了。生产者接受的ack来自broker,不是消费者。-.-
如果消费方出现问题,那么消费方不能发送ack响应,那生产者会重复发送消息,这种场景下消费者也不会出现重复消费的问题。
生产者投递消息后,接收到的ack是来自消费者。消费者可以设置消费完消息,再给生产者发送ack=true的响应。
努力重试的过程需要对库里的数据进行update动作,这个动作是根据上一次的MessageId来进行update,而不是insert动作,这时候的更新的只是order的状态,以及努力次数,因此重复入库的情况,也就是重复消费的情况不存在。
个人觉得看具体业务实现了,如果消费方出现异常,理论上你操作的业务表和日志表处于同一事物,也就是说最终没能更新发送状态,也没能消费成功,这个时候走定时任务,然后发送(二次投递)-->再次消费。
如果说由于网络原因,你消费成功了,然后服务得到失败的结果,而恰好你有重试策略(当然很多业务场景都需要设置这个策略),再次发送了,那么必然导致数据重复消费。这个时候就靠你消费者具体的设计了,防止重复消费,做幂等处理。
RabbitMQ消息中间件极速入门与实战
42055 学习 · 143 问题
相似问题