分布式中防止重复消费

全局唯一ID(UUID、雪花算法ID等),让每条请求或消息都有一个唯一的Key------那么这个id是不是就在消息队列里面?不是在消费端的业务层生成的

好问题!这个唯一 ID 可以在不同环节生成 ,但通常是消息产生方(生产者)就生成好,然后随着消息一起放进消息队列传到消费者。

原因:

  • 消息的唯一性应该和消息绑定

    如果在消费端才生成唯一 ID,就失去了去重的意义,因为同一条消息多次被投递时,消费端生成的 ID 也会不同,无法判断它们是重复的。

  • 正确做法

    生产者在发送消息时生成唯一 ID,并作为消息字段传递,比如:

    json 复制代码
    {
      "msg_id": "uuid-xxxx",
      "user_id": 1001,
      "product_id": 2002,
      "timestamp": 1690000000
    }

    消费者拿到 msg_id 做去重。


📌 流程:

  1. 生产端生成唯一 ID(UUID/雪花算法等),写入消息内容;
  2. 将消息发送到 MQ;
  3. 消费端拿到消息 → 查询 Redis/DB 看 msg_id 是否已消费过;
  4. 如果消费过:丢弃;
  5. 如果没消费过:执行业务逻辑 → 标记已消费。

✅ 所以:
唯一 ID 是随着消息走的,通常在生产端生成并写进 MQ,而不是消费端生成。

那么防止重复消费,生产者会生成唯一ID,不管是在MQ还是在消费者,都会保存已经存储或者处理的ID,MQ接收的时候,和消费者进行处理的时候,都会先查询存储的id,看是否已经接收或者处理了?

对!你的理解很接近完整逻辑了,不过可以更精确一点:


🔍 关键点是不同环节"去重"的责任范围:

环节 是否需要存储和检查 ID 目的
生产者 一般 不检查,只负责生成唯一 ID 保证每条消息天然有唯一标识
消息队列(MQ) 看具体 MQ: - Kafka:有 offset,不做业务级去重 - RabbitMQ:不做业务级去重 - RocketMQ:可配置去重 结论:大多数 MQ 不做业务级去重 保证消息可靠投递,但不负责业务幂等
消费者 一定要检查 :消费前查 Redis/DB 看 msg_id 是否已处理过 防止重复消费、保证业务幂等性

🧩 完整流程

  1. 生产端生成唯一 ID

    json 复制代码
    {
      "msg_id": "uuid-1234-5678",
      "user_id": 1,
      "product_id": 100,
      "timestamp": 1690000000
    }
  2. 消息进入 MQ

    • MQ保证可靠存储和投递,但不一定去重(比如 Kafka 的 offset 是流式顺序,不去重)。
  3. 消费者拿消息 → 检查去重表

    • 查 Redis 或 DB,看 msg_id 是否存在;
  4. 不存在:执行业务逻辑,执行成功后写入去重表

  5. 存在:直接丢弃,防止重复处理


💡 总结:

  • 唯一 ID 主要是给消费者用来防重复消费的
  • MQ 大多不负责业务去重,它只保证"至少一次"投递;
  • 所以消费者必须做最终幂等性保障。

MQ 大多不负责业务去重,它只保证"至少一次"投递;------ 也就是说,MQ会存储重复消息?

对,可以这么理解:

大多数主流 MQ(Kafka、RabbitMQ、RocketMQ 等)并不做业务级去重,所以可能会"存储并投递重复消息"。

这是它们设计上的取舍。


🔍 详细解释:

  1. MQ 的设计目标

    • MQ关注的是消息的可靠性、顺序性和高吞吐,核心保证是"至少一次投递"(At-least-once)。
    • 为了确保消息不丢,生产端、Broker、消费端都可能重试,这就容易导致重复消息。
    • MQ 不做业务级去重,因为去重需要存储所有消息 ID、增加复杂度、降低性能。
  2. 为什么会产生重复消息

    • 生产者端重复发送:发送超时或网络问题,生产者以为没发成功,会重发一次;
    • Broker重复投递:消费端 ACK 超时或失败,Broker会重发;
    • 分区副本恢复:Kafka等在Leader切换时,也可能让消费端再次拉到之前的消息。
  3. 设计哲学

    • MQ通常选择简单的"至少一次"保证,让消费者来处理幂等性。
    • 因为消费者业务逻辑最了解消息是否可重复执行。

💡 结论

  • MQ可以存储重复消息,也可能重复投递;
  • 去重责任交给消费者,通过唯一ID+去重表或幂等逻辑解决。
相关推荐
tan77º17 小时前
【项目】分布式Json-RPC框架 - 应用层实现
linux·服务器·网络·分布式·网络协议·rpc·json
JAMES费18 小时前
分布式AI算力系统番外篇-----超体的现实《星核》
人工智能·分布式
计时开始不睡觉19 小时前
从 @Schedule 到 XXL-JOB:分布式定时任务的演进与实践
java·分布式·spring·xxl-job·定时任务
2301_7816686119 小时前
Elasticsearch(高性能分布式搜索引擎)01
分布式·elasticsearch·搜索引擎
CHEN5_021 天前
【CouponHub开发记录】SpringAop和分布式锁进行自定义注解实现防止重复提交
java·分布式·spring·项目
EQ-雪梨蛋花汤1 天前
【代码里的英雄传】Dubbo 的一生:一位分布式勇士的传奇旅程
分布式·dubbo
Leo Kuo1 天前
ETCD学习笔记
分布式·系统架构·go·etcd
工藤学编程1 天前
深入浅出 RabbitMQ-RabbitMQ消息确认机制(ACK)
分布式·rabbitmq·ruby
心月狐的流火号1 天前
分布式事务XA模式:基于数据库的2PC
分布式·后端