1. 消息重复消费问题的本质在分布式消息系统中消息重复消费是个经典难题。我经历过一个电商项目促销期间由于消息重复导致同一个订单被处理了三次差点造成重大损失。这个问题看似简单实际涉及消息系统的多个核心机制。消息重复的根本原因在于消息系统无法保证Exactly-Once的语义。就像快递员送包裹当网络抖动或超时发生时发件人无法确定对方是否收到只能选择重发。在RocketMQ中这种至少一次的投递机制必然会导致重复消费的可能。2. RocketMQ的消息投递机制解析2.1 消息消费的完整生命周期一个消息从生产到消费完成会经历以下关键阶段生产者发送消息到BrokerBroker持久化消息并返回ACK消费者拉取消息消费者处理完成后提交消费位点(offset)Broker标记消息为已消费2.2 可能产生重复的关键环节在实际运行中以下场景会导致重复网络抖动消费者处理成功但提交offset失败客户端重启内存中已处理但未持久化的offset丢失负载均衡消费者重新分配队列时offset回滚事务消息二阶段提交失败后的回查重试3. 消息去重的核心解决方案3.1 幂等性设计推荐方案这是最根本的解决方案。就像银行转账系统无论操作多少次最终结果应该一致。实现方式包括// 使用Redis实现简易幂等控制 public boolean processMessage(Message message) { String msgId message.getMsgId(); // SETNX 过期时间 Boolean result redisTemplate.opsForValue() .setIfAbsent(MSG_ID: msgId, 1, 24, TimeUnit.HOURS); if (!result) { return false; // 已处理过 } // 实际业务处理 return doRealBusiness(message); }关键参数选择过期时间建议大于消息最大保留时间默认3天Key设计建议包含业务标识如ORDER_MSG:{msgId}3.2 事务状态表方案适合强一致性要求的场景如金融交易CREATE TABLE msg_transaction ( id BIGINT PRIMARY KEY, biz_id VARCHAR(64) UNIQUE, -- 业务唯一ID status TINYINT, -- 0未处理 1处理中 2处理成功 create_time DATETIME, update_time DATETIME, INDEX idx_biz_id (biz_id) );处理流程开启本地事务插入或更新状态记录执行业务逻辑提交事务3.3 RocketMQ自身机制4.5版本支持的消息去重功能# broker配置 enableConsumeMessageConcurrentlyfalse enableConsumeMessageOrderlytrue4. 不同场景下的方案选型4.1 普通消息场景方案适用场景优缺点幂等设计大部分业务场景实现简单但对代码有侵入性状态表强一致性要求可靠但性能较低消息属性简单业务依赖客户端实现4.2 顺序消息场景顺序消息需要特别注意必须保证同一个消息队列(MessageQueue)消费失败会阻塞后续消息建议配合本地事务实现// 顺序消息消费示例 consumer.registerMessageListener(new MessageListenerOrderly() { Override public ConsumeOrderlyStatus consumeMessage(ListMessageExt msgs, ConsumeOrderlyContext context) { try { // 业务处理 return ConsumeOrderlyStatus.SUCCESS; } catch (Exception e) { return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT; } } });5. 实战中的经验技巧5.1 消息轨迹追踪建议为每条消息添加唯一traceIdMessage message new Message(); message.putUserProperty(traceId, UUID.randomUUID().toString());5.2 消费监控配置关键监控指标# 消费超时时间默认15分钟 rocketmq.consumer.consumeTimeout15m # 最大重试次数默认16次 rocketmq.consumer.maxReconsumeTimes165.3 常见问题排查消息堆积导致重复检查消费者线程数consumeThreadMin/consumeThreadMax优化消费逻辑耗时重复消费但无异常日志检查是否为网络分区导致验证Broker的HA切换记录事务消息重复-- 检查半事务消息 SELECT * FROM rmq_half_message WHERE msg_id xxx;6. 高级场景解决方案6.1 分布式锁方案对于跨系统调用的场景RedissonClient redisson Redisson.create(); RLock lock redisson.getLock(MSG_LOCK: message.getMsgId()); try { if (lock.tryLock(3, 30, TimeUnit.SECONDS)) { // 处理业务 } } finally { lock.unlock(); }6.2 消息延迟去重适用于最终一致性场景// 使用延迟双删策略 redisTemplate.opsForValue().set(key, value, 30, TimeUnit.SECONDS); // 业务处理... // 30秒后异步删除 asyncTaskExecutor.execute(() - { Thread.sleep(30000); redisTemplate.delete(key); });6.3 批处理消息去重批量消费时的优化方案public void processBatch(ListMessage messages) { MapString, Message uniqueMessages messages.stream() .collect(Collectors.toMap( Message::getMsgId, Function.identity(), (oldVal, newVal) - oldVal)); // 处理去重后的消息 }7. 性能优化建议Redis集群选择消息去重的Redis建议使用集群版合理设置分片大小避免热点本地缓存配合// Guava Cache做一级缓存 CacheString, Boolean localCache CacheBuilder.newBuilder() .maximumSize(100000) .expireAfterWrite(1, TimeUnit.HOURS) .build();消息过滤优化// 使用SQL表达式过滤 consumer.subscribe(TopicTest, MessageSelector.bySql(TAGS IS NOT NULL AND created_time 1698765432));在实际项目中我们综合使用幂等设计状态表的方式将重复消费率从最初的0.3%降到了0.001%以下。关键是要根据业务特点选择合适的技术组合并建立完善的监控体系。
企业数字化 ERP 产品动态
相关推荐
微信小程序电影购票源码:含选座锁座与微信支付完整闭环 简介:这是一份面向微信小程序初学者与进阶开发者的电影购票类实战源码,聚焦轻量级生活服务场景,帮助开发者掌握小程序核心开发流程与第三方服务集成方法。资源包含92个文件,涵盖14个JS逻辑文件(含app.js、server.js等主… · 2026/11/4 15:00:41
RH2288HV3 BIOS升级实战:从拆包到刷写与排错 简介:面向企业运维人员与数据中心管理员,这份资源提供华为RH2288HV3机架服务器的BIOS固件更新包,用于修复底层缺陷、提升系统稳定性与硬件兼容性,适合需要定期维护企业级服务器、通过iBMC远程完成固件升级的读者。压缩包共4个文件… · 2026/11/4 14:59:39
主机折腾前的安全底线:数据备份、系统稳定与账号防护全指南 身边不少朋友在主机上栽过跟头,最惨的一次是某位朋友把攒了两年的存档丢干净了,前一天还在打最终章,第二天开机发现存档列表空了一半,人直接懵在沙发上。这类事听起来像小概率,实际上每年都在重复发生:一次… · 2026/11/4 14:59:39
ok-ww 鸣潮后台刷声骸与一键日常快速指南 ok-ww 鸣潮后台刷声骸与一键日常快速指南 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves
ok-ww 是一个面向《鸣潮》的开源自动化工… · 2026/11/4 15:40:43
阅读APP书源导入实操指南:22个书源一次配好,10分钟开始阅读 阅读APP书源导入实操指南:22个书源一次配好,10分钟开始阅读 【免费下载链接】Yuedu 📚「阅读」自用书源分享 项目地址: https://gitcode.com/gh_mirrors/yu/Yuedu
阅读APP装好并不能直接取书,第一步是导入书源。本文带你用… · 2026/11/4 15:40:43
Kornia相机位姿估计避坑手册:4个角点反推相机位置与朝向 Kornia相机位姿估计避坑手册:4个角点反推相机位置与朝向 【免费下载链接】kornia 🐍 空间人工智能的几何计算机视觉库 项目地址: https://gitcode.com/kornia/kornia
🎯 手里只有一张图、几个角点的2D-3D对应,能不能反推相… · 2026/11/4 15:40:43
10分钟导入22个阅读APP书源:跑通指南 10分钟导入22个阅读APP书源:跑通指南 【免费下载链接】Yuedu 📚「阅读」自用书源分享 项目地址: https://gitcode.com/gh_mirrors/yu/Yuedu
📡 一句话说清你在干什么
「阅读」APP 装完就是个空壳,不做阅读APP书源导入&… · 2026/11/4 15:40:43
二叉树之层序遍历(牛客round92——E题) /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 15:40:43
Trae Agent 离线模式:不联网也能跑通 Agent 的三步教程 Trae Agent 离线模式:不联网也能跑通 Agent 的三步教程 【免费下载链接】trae-agent Trae Agent is an LLM-based agent for general purpose software engineering tasks. 项目地址: https://gitcode.com/gh_mirrors/tr/trae-agent
公司内网与外网完全隔离&… · 2026/11/4 15:39:43
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38