RocketMQ—RocketMQ消息重复消费问题

RocketMQ---RocketMQ消息重复消费问题

重复消费问题的描述

什么情况下会发生重复消费的问题:

  1. 生产者多次投递消息:如果生产者发送消息时,连接有延迟,MQ还没收到消息,生产者又发送了一次消息;

  2. 消费者方扩容时会重试:

    topic中有四个queue,queue2中有一个消息MSG,如果此时只有一个消费者,MSG就会被被consumer1获取到;

    但是consumer1获取到消息时,位点还没来得及前移,又有了一个消费者Consumer2,这样就会产生重平衡;

    Consumer1消费0和1队列,Consumer2消费2和3队列,因为上一步的消息还没消费成功,所以会给Consumer2一份消息,这样就会产生重复消费的问题。

重复消费问题的解决方案

一般情况下,我们会在消费者端解决重复消费的问题,消费者端需要进行去重,去重关键点就是要找到消息的唯一标记,所以我们在发送消息时会带有一个key,消费者拿到相同的key就不进行操作了。(一般使用redis存储消费过的key,或者使用mysql存储消费记录,把key设置成唯一索引。)

mysql解决方案

简单建一个去重表,有id,key两个字段,key设置唯一索引。

错误做法

java 复制代码
if(key存在){
	直接返回;
}
执行业务逻辑。
插入key记录到MySQL;

这样做是不正确的,因为不能保证并发安全,如果有两个线程同时进来,这样都会查不到这个key,都会执行消费的逻辑。

正确做法

java 复制代码
try{
    插入key记录到MySQL;//MySQL唯一索引内部会保证唯一
}catch (SQLException e) {
    if (e instanceof SQLIntegrityConstraintViolationException) {
        // 唯一索引冲突异常
        // 说明消息来过了
        记录日志;
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
    其他错误依然会报错,会重新投递到消息队列;
}
处理业务逻辑
如果业务报错 则删除掉这个去重表记录
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
相关推荐
何中应2 天前
在windows本地部署RabbitMQ
分布式·消息队列·rabbitmq
qq_297574672 天前
RocketMQ系列文章(入门篇第6篇):延时消息+顺序消息实战
spring boot·rocketmq·java-rocketmq
AutoMQ4 天前
别再每月浪费数千美元:拆解 AWS/GCP Kafka 背后的隐性账单
kafka·消息队列·aws
Micro麦可乐5 天前
Redis只会用来做缓存?解锁Redis非缓存的九个应用场景,90%程序员不知道的隐藏技能
数据库·redis·缓存·消息队列·分布式锁·延迟队列·布隆过滤器
刘~浪地球6 天前
消息队列--RocketMQ 架构设计与优化
架构·rocketmq
Rick19938 天前
rabbitmq, rocketmq, kafka这三种消息如何分别保住可靠性,顺序性,以及应用场景?
kafka·rabbitmq·rocketmq
有梦想的小何9 天前
从0到1搭建可靠消息链路:RocketMQ重试 + Redis幂等实战
java·redis·bootstrap·rocketmq
鬼先生_sir10 天前
SpringCloud-Stream + RocketMQ/Kafka
spring cloud·kafka·rocketmq·stream
恋喵大鲤鱼12 天前
分布式消息投递模型快速上手
消息队列·投递模型
少许极端14 天前
消息队列5-RabbitMQ的高级特性和MQ的应用问题与解决方案-事务、消息分发的应用、幂等性保证、顺序性保证、消息积压的解决
分布式·消息队列·rabbitmq