RabbitMQ 消息可靠性:如何确保消息不会丢失?全场景解决方案+流程图+实战配置
-
- 前言
- 一、消息丢失三大场景:消息会在哪里丢失?
-
- 1.1 三大丢失场景流程图
- 1.2 场景详细说明
- 二、解决方案总览:确保消息不丢失的5大核心机制
- 三、阶段一:生产者防丢失(Confirm + Return)
-
- 3.1 丢失原因
- 3.2 解决方案1:生产者 Confirm 确认机制
- 3.3 解决方案2:Return 回退机制
- 3.4 生产者可靠性流程图
- 3.5 SpringBoot 配置开启确认机制
- 四、阶段二:MQ 服务端防丢失(持久化)
-
- 4.1 丢失原因
- 4.2 解决方案:三重持久化(必须全部开启)
- 4.3 持久化工作流程图
- 4.4 代码实战:声明持久化队列与消息
- 五、阶段三:消费者防丢失(手动 ACK)
-
- 5.1 丢失原因
- 5.2 解决方案:手动 ACK 确认机制
- 5.3 手动 ACK 流程图
- 5.4 SpringBoot 配置手动 ACK
- 5.5 消费者代码示例
- 六、兜底保障:死信队列 DLX(处理无法消费的消息)
-
- 6.1 作用
- 6.2 死信队列流程图
- 七、生产环境消息不丢失完整配置清单(直接复制)
-
- 7.1 YML 核心配置
- 7.2 代码必须遵守
- 八、总结:一张表记住所有防丢失方案
- 九、全文总结
-
- 确保 RabbitMQ 消息不丢失的核心口诀:
- 文末说明
|
🌺The Begin🌺点点关注,收藏不迷路🌺 |
前言
在生产环境使用 RabbitMQ 时,消息丢失是最严重的问题之一。消息一旦丢失,可能导致订单失效、数据不一致、业务异常等灾难性后果。
消息丢失可能发生在生产者发送阶段、MQ存储阶段、消费者消费阶段。本文将从全链路角度,详细讲解每一个环节的丢失原因、解决方案、配置代码,让你彻底实现 RabbitMQ 消息零丢失。
一、消息丢失三大场景:消息会在哪里丢失?
RabbitMQ 消息从发送到消费,一共分为3个阶段,每个阶段都可能丢失消息:
1.1 三大丢失场景流程图
#mermaid-svg-kcAUPjBgdam02tPz{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kcAUPjBgdam02tPz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kcAUPjBgdam02tPz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kcAUPjBgdam02tPz .error-icon{fill:#552222;}#mermaid-svg-kcAUPjBgdam02tPz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kcAUPjBgdam02tPz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kcAUPjBgdam02tPz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kcAUPjBgdam02tPz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kcAUPjBgdam02tPz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kcAUPjBgdam02tPz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kcAUPjBgdam02tPz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kcAUPjBgdam02tPz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kcAUPjBgdam02tPz .marker.cross{stroke:#333333;}#mermaid-svg-kcAUPjBgdam02tPz svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kcAUPjBgdam02tPz p{margin:0;}#mermaid-svg-kcAUPjBgdam02tPz .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-kcAUPjBgdam02tPz .cluster-label text{fill:#333;}#mermaid-svg-kcAUPjBgdam02tPz .cluster-label span{color:#333;}#mermaid-svg-kcAUPjBgdam02tPz .cluster-label span p{background-color:transparent;}#mermaid-svg-kcAUPjBgdam02tPz .label text,#mermaid-svg-kcAUPjBgdam02tPz span{fill:#333;color:#333;}#mermaid-svg-kcAUPjBgdam02tPz .node rect,#mermaid-svg-kcAUPjBgdam02tPz .node circle,#mermaid-svg-kcAUPjBgdam02tPz .node ellipse,#mermaid-svg-kcAUPjBgdam02tPz .node polygon,#mermaid-svg-kcAUPjBgdam02tPz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kcAUPjBgdam02tPz .rough-node .label text,#mermaid-svg-kcAUPjBgdam02tPz .node .label text,#mermaid-svg-kcAUPjBgdam02tPz .image-shape .label,#mermaid-svg-kcAUPjBgdam02tPz .icon-shape .label{text-anchor:middle;}#mermaid-svg-kcAUPjBgdam02tPz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kcAUPjBgdam02tPz .rough-node .label,#mermaid-svg-kcAUPjBgdam02tPz .node .label,#mermaid-svg-kcAUPjBgdam02tPz .image-shape .label,#mermaid-svg-kcAUPjBgdam02tPz .icon-shape .label{text-align:center;}#mermaid-svg-kcAUPjBgdam02tPz .node.clickable{cursor:pointer;}#mermaid-svg-kcAUPjBgdam02tPz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kcAUPjBgdam02tPz .arrowheadPath{fill:#333333;}#mermaid-svg-kcAUPjBgdam02tPz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kcAUPjBgdam02tPz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kcAUPjBgdam02tPz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kcAUPjBgdam02tPz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kcAUPjBgdam02tPz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kcAUPjBgdam02tPz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kcAUPjBgdam02tPz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kcAUPjBgdam02tPz .cluster text{fill:#333;}#mermaid-svg-kcAUPjBgdam02tPz .cluster span{color:#333;}#mermaid-svg-kcAUPjBgdam02tPz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kcAUPjBgdam02tPz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kcAUPjBgdam02tPz rect.text{fill:none;stroke-width:0;}#mermaid-svg-kcAUPjBgdam02tPz .icon-shape,#mermaid-svg-kcAUPjBgdam02tPz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kcAUPjBgdam02tPz .icon-shape p,#mermaid-svg-kcAUPjBgdam02tPz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kcAUPjBgdam02tPz .icon-shape .label rect,#mermaid-svg-kcAUPjBgdam02tPz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kcAUPjBgdam02tPz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kcAUPjBgdam02tPz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kcAUPjBgdam02tPz :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
1.网络故障/发送失败
2.MQ宕机/未持久化
3.消费失败/未ACK
生产者发送消息
丢失点1
RabbitMQ 服务器
丢失点2
消费者消费消息
丢失点3
1.2 场景详细说明
二、解决方案总览:确保消息不丢失的5大核心机制
要实现全链路可靠投递,必须同时开启以下机制:
三、阶段一:生产者防丢失(Confirm + Return)
3.1 丢失原因
- 网络波动,消息未送达 MQ
- 交换机不存在,路由键错误,消息被丢弃
3.2 解决方案1:生产者 Confirm 确认机制
作用:MQ 收到消息后,会返回一个确认信号给生产者,生产者感知到消息已送达。
3.3 解决方案2:Return 回退机制
作用:如果消息无法路由到队列,MQ 会把消息退回给生产者,而不是直接丢弃。
3.4 生产者可靠性流程图
#mermaid-svg-ehuAiCo19Y6c1FH5{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ehuAiCo19Y6c1FH5 .error-icon{fill:#552222;}#mermaid-svg-ehuAiCo19Y6c1FH5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ehuAiCo19Y6c1FH5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .marker.cross{stroke:#333333;}#mermaid-svg-ehuAiCo19Y6c1FH5 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ehuAiCo19Y6c1FH5 p{margin:0;}#mermaid-svg-ehuAiCo19Y6c1FH5 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster-label text{fill:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster-label span{color:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster-label span p{background-color:transparent;}#mermaid-svg-ehuAiCo19Y6c1FH5 .label text,#mermaid-svg-ehuAiCo19Y6c1FH5 span{fill:#333;color:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .node rect,#mermaid-svg-ehuAiCo19Y6c1FH5 .node circle,#mermaid-svg-ehuAiCo19Y6c1FH5 .node ellipse,#mermaid-svg-ehuAiCo19Y6c1FH5 .node polygon,#mermaid-svg-ehuAiCo19Y6c1FH5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .rough-node .label text,#mermaid-svg-ehuAiCo19Y6c1FH5 .node .label text,#mermaid-svg-ehuAiCo19Y6c1FH5 .image-shape .label,#mermaid-svg-ehuAiCo19Y6c1FH5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ehuAiCo19Y6c1FH5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .rough-node .label,#mermaid-svg-ehuAiCo19Y6c1FH5 .node .label,#mermaid-svg-ehuAiCo19Y6c1FH5 .image-shape .label,#mermaid-svg-ehuAiCo19Y6c1FH5 .icon-shape .label{text-align:center;}#mermaid-svg-ehuAiCo19Y6c1FH5 .node.clickable{cursor:pointer;}#mermaid-svg-ehuAiCo19Y6c1FH5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .arrowheadPath{fill:#333333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ehuAiCo19Y6c1FH5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ehuAiCo19Y6c1FH5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ehuAiCo19Y6c1FH5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster text{fill:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 .cluster span{color:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ehuAiCo19Y6c1FH5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ehuAiCo19Y6c1FH5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ehuAiCo19Y6c1FH5 .icon-shape,#mermaid-svg-ehuAiCo19Y6c1FH5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ehuAiCo19Y6c1FH5 .icon-shape p,#mermaid-svg-ehuAiCo19Y6c1FH5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ehuAiCo19Y6c1FH5 .icon-shape .label rect,#mermaid-svg-ehuAiCo19Y6c1FH5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ehuAiCo19Y6c1FH5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ehuAiCo19Y6c1FH5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ehuAiCo19Y6c1FH5 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
生产者发送消息
交换机收到?
返回Confirm ACK
返回Confirm NACK/超时重发
能路由到队列?
正常入队
Return消息回退
3.5 SpringBoot 配置开启确认机制
spring:
rabbitmq:
publisher-confirm-type: correlated # 开启发布确认
publisher-returns: true # 开启消息回退
template:
mandatory: true # 开启失败回退
四、阶段二:MQ 服务端防丢失(持久化)
4.1 丢失原因
- RabbitMQ 服务器宕机、重启
- 队列、消息是内存存储,重启即清空
4.2 解决方案:三重持久化(必须全部开启)
4.3 持久化工作流程图
#mermaid-svg-gpdXdKOw2lE6WT8q{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gpdXdKOw2lE6WT8q .error-icon{fill:#552222;}#mermaid-svg-gpdXdKOw2lE6WT8q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gpdXdKOw2lE6WT8q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gpdXdKOw2lE6WT8q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gpdXdKOw2lE6WT8q .marker.cross{stroke:#333333;}#mermaid-svg-gpdXdKOw2lE6WT8q svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gpdXdKOw2lE6WT8q p{margin:0;}#mermaid-svg-gpdXdKOw2lE6WT8q .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster-label text{fill:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster-label span{color:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster-label span p{background-color:transparent;}#mermaid-svg-gpdXdKOw2lE6WT8q .label text,#mermaid-svg-gpdXdKOw2lE6WT8q span{fill:#333;color:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q .node rect,#mermaid-svg-gpdXdKOw2lE6WT8q .node circle,#mermaid-svg-gpdXdKOw2lE6WT8q .node ellipse,#mermaid-svg-gpdXdKOw2lE6WT8q .node polygon,#mermaid-svg-gpdXdKOw2lE6WT8q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gpdXdKOw2lE6WT8q .rough-node .label text,#mermaid-svg-gpdXdKOw2lE6WT8q .node .label text,#mermaid-svg-gpdXdKOw2lE6WT8q .image-shape .label,#mermaid-svg-gpdXdKOw2lE6WT8q .icon-shape .label{text-anchor:middle;}#mermaid-svg-gpdXdKOw2lE6WT8q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gpdXdKOw2lE6WT8q .rough-node .label,#mermaid-svg-gpdXdKOw2lE6WT8q .node .label,#mermaid-svg-gpdXdKOw2lE6WT8q .image-shape .label,#mermaid-svg-gpdXdKOw2lE6WT8q .icon-shape .label{text-align:center;}#mermaid-svg-gpdXdKOw2lE6WT8q .node.clickable{cursor:pointer;}#mermaid-svg-gpdXdKOw2lE6WT8q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gpdXdKOw2lE6WT8q .arrowheadPath{fill:#333333;}#mermaid-svg-gpdXdKOw2lE6WT8q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gpdXdKOw2lE6WT8q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gpdXdKOw2lE6WT8q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gpdXdKOw2lE6WT8q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gpdXdKOw2lE6WT8q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gpdXdKOw2lE6WT8q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster text{fill:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q .cluster span{color:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gpdXdKOw2lE6WT8q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gpdXdKOw2lE6WT8q rect.text{fill:none;stroke-width:0;}#mermaid-svg-gpdXdKOw2lE6WT8q .icon-shape,#mermaid-svg-gpdXdKOw2lE6WT8q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gpdXdKOw2lE6WT8q .icon-shape p,#mermaid-svg-gpdXdKOw2lE6WT8q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gpdXdKOw2lE6WT8q .icon-shape .label rect,#mermaid-svg-gpdXdKOw2lE6WT8q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gpdXdKOw2lE6WT8q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gpdXdKOw2lE6WT8q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gpdXdKOw2lE6WT8q :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
消息发送
交换机持久化
队列持久化
消息写入磁盘
MQ重启
从磁盘加载消息
消息不丢失
4.4 代码实战:声明持久化队列与消息
// 1. 声明持久化交换机
@Bean
public DirectExchange orderExchange(){
// true 表示持久化
return new DirectExchange("order.exchange", true, false);
}
// 2. 声明持久化队列
@Bean
public Queue orderQueue(){
// true 表示持久化
return new Queue("order.queue", true);
}
// 3. 发送持久化消息
rabbitTemplate.convertAndSend(exchange, routingKey, msg, message -> {
// 设置消息持久化
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
return message;
});
五、阶段三:消费者防丢失(手动 ACK)
5.1 丢失原因
- 自动 ACK 模式下,消费者一拿到消息,MQ 就立即删除消息
- 如果消费者还没处理完就宕机,消息就永久丢失
5.2 解决方案:手动 ACK 确认机制
工作方式:
- 消费者处理完业务逻辑之后,手动发送 ACK 命令
- MQ 收到 ACK 才会删除消息
- 如果消费者宕机未发送 ACK,MQ 会将消息重新入队,投递给其他消费者
5.3 手动 ACK 流程图
#mermaid-svg-3XMtmQHVr2xIOaAY{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3XMtmQHVr2xIOaAY .error-icon{fill:#552222;}#mermaid-svg-3XMtmQHVr2xIOaAY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3XMtmQHVr2xIOaAY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3XMtmQHVr2xIOaAY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3XMtmQHVr2xIOaAY .marker.cross{stroke:#333333;}#mermaid-svg-3XMtmQHVr2xIOaAY svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3XMtmQHVr2xIOaAY p{margin:0;}#mermaid-svg-3XMtmQHVr2xIOaAY .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster-label text{fill:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster-label span{color:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster-label span p{background-color:transparent;}#mermaid-svg-3XMtmQHVr2xIOaAY .label text,#mermaid-svg-3XMtmQHVr2xIOaAY span{fill:#333;color:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY .node rect,#mermaid-svg-3XMtmQHVr2xIOaAY .node circle,#mermaid-svg-3XMtmQHVr2xIOaAY .node ellipse,#mermaid-svg-3XMtmQHVr2xIOaAY .node polygon,#mermaid-svg-3XMtmQHVr2xIOaAY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3XMtmQHVr2xIOaAY .rough-node .label text,#mermaid-svg-3XMtmQHVr2xIOaAY .node .label text,#mermaid-svg-3XMtmQHVr2xIOaAY .image-shape .label,#mermaid-svg-3XMtmQHVr2xIOaAY .icon-shape .label{text-anchor:middle;}#mermaid-svg-3XMtmQHVr2xIOaAY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3XMtmQHVr2xIOaAY .rough-node .label,#mermaid-svg-3XMtmQHVr2xIOaAY .node .label,#mermaid-svg-3XMtmQHVr2xIOaAY .image-shape .label,#mermaid-svg-3XMtmQHVr2xIOaAY .icon-shape .label{text-align:center;}#mermaid-svg-3XMtmQHVr2xIOaAY .node.clickable{cursor:pointer;}#mermaid-svg-3XMtmQHVr2xIOaAY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3XMtmQHVr2xIOaAY .arrowheadPath{fill:#333333;}#mermaid-svg-3XMtmQHVr2xIOaAY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3XMtmQHVr2xIOaAY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3XMtmQHVr2xIOaAY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3XMtmQHVr2xIOaAY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3XMtmQHVr2xIOaAY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3XMtmQHVr2xIOaAY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster text{fill:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY .cluster span{color:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3XMtmQHVr2xIOaAY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3XMtmQHVr2xIOaAY rect.text{fill:none;stroke-width:0;}#mermaid-svg-3XMtmQHVr2xIOaAY .icon-shape,#mermaid-svg-3XMtmQHVr2xIOaAY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3XMtmQHVr2xIOaAY .icon-shape p,#mermaid-svg-3XMtmQHVr2xIOaAY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3XMtmQHVr2xIOaAY .icon-shape .label rect,#mermaid-svg-3XMtmQHVr2xIOaAY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3XMtmQHVr2xIOaAY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3XMtmQHVr2xIOaAY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3XMtmQHVr2xIOaAY :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
MQ推送消息
消费者接收
执行业务逻辑
成功?
手动发送ACK
发送NACK/拒绝
MQ删除消息
MQ重新入队/死信
5.4 SpringBoot 配置手动 ACK
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual # 手动确认
5.5 消费者代码示例
@RabbitListener(queues = "order.queue")
public void receiveMsg(Message message, Channel channel) throws IOException {
long tag = message.getMessageProperties().getDeliveryTag();
try {
String msg = new String(message.getBody());
System.out.println("消费消息:" + msg);
// 1. 业务处理成功,手动确认
channel.basicAck(tag, false);
} catch (Exception e) {
// 2. 业务处理失败,拒绝消息,重新入队
channel.basicNack(tag, false, true);
}
}
六、兜底保障:死信队列 DLX(处理无法消费的消息)
6.1 作用
即使开启了所有机制,仍可能出现消息格式错误、业务异常、多次重试失败的消息,这些消息会进入死信队列,不会被丢弃,方便后续人工处理。
6.2 死信队列流程图
#mermaid-svg-oOoUCBcfidCV4dBY{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oOoUCBcfidCV4dBY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oOoUCBcfidCV4dBY .error-icon{fill:#552222;}#mermaid-svg-oOoUCBcfidCV4dBY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oOoUCBcfidCV4dBY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oOoUCBcfidCV4dBY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oOoUCBcfidCV4dBY .marker.cross{stroke:#333333;}#mermaid-svg-oOoUCBcfidCV4dBY svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oOoUCBcfidCV4dBY p{margin:0;}#mermaid-svg-oOoUCBcfidCV4dBY .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-oOoUCBcfidCV4dBY .cluster-label text{fill:#333;}#mermaid-svg-oOoUCBcfidCV4dBY .cluster-label span{color:#333;}#mermaid-svg-oOoUCBcfidCV4dBY .cluster-label span p{background-color:transparent;}#mermaid-svg-oOoUCBcfidCV4dBY .label text,#mermaid-svg-oOoUCBcfidCV4dBY span{fill:#333;color:#333;}#mermaid-svg-oOoUCBcfidCV4dBY .node rect,#mermaid-svg-oOoUCBcfidCV4dBY .node circle,#mermaid-svg-oOoUCBcfidCV4dBY .node ellipse,#mermaid-svg-oOoUCBcfidCV4dBY .node polygon,#mermaid-svg-oOoUCBcfidCV4dBY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oOoUCBcfidCV4dBY .rough-node .label text,#mermaid-svg-oOoUCBcfidCV4dBY .node .label text,#mermaid-svg-oOoUCBcfidCV4dBY .image-shape .label,#mermaid-svg-oOoUCBcfidCV4dBY .icon-shape .label{text-anchor:middle;}#mermaid-svg-oOoUCBcfidCV4dBY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oOoUCBcfidCV4dBY .rough-node .label,#mermaid-svg-oOoUCBcfidCV4dBY .node .label,#mermaid-svg-oOoUCBcfidCV4dBY .image-shape .label,#mermaid-svg-oOoUCBcfidCV4dBY .icon-shape .label{text-align:center;}#mermaid-svg-oOoUCBcfidCV4dBY .node.clickable{cursor:pointer;}#mermaid-svg-oOoUCBcfidCV4dBY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oOoUCBcfidCV4dBY .arrowheadPath{fill:#333333;}#mermaid-svg-oOoUCBcfidCV4dBY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oOoUCBcfidCV4dBY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oOoUCBcfidCV4dBY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oOoUCBcfidCV4dBY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oOoUCBcfidCV4dBY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oOoUCBcfidCV4dBY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oOoUCBcfidCV4dBY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oOoUCBcfidCV4dBY .cluster text{fill:#333;}#mermaid-svg-oOoUCBcfidCV4dBY .cluster span{color:#333;}#mermaid-svg-oOoUCBcfidCV4dBY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oOoUCBcfidCV4dBY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oOoUCBcfidCV4dBY rect.text{fill:none;stroke-width:0;}#mermaid-svg-oOoUCBcfidCV4dBY .icon-shape,#mermaid-svg-oOoUCBcfidCV4dBY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oOoUCBcfidCV4dBY .icon-shape p,#mermaid-svg-oOoUCBcfidCV4dBY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oOoUCBcfidCV4dBY .icon-shape .label rect,#mermaid-svg-oOoUCBcfidCV4dBY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oOoUCBcfidCV4dBY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oOoUCBcfidCV4dBY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oOoUCBcfidCV4dBY :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
正常队列
消息过期/拒绝/队列满
死信交换机
死信队列
人工排查/补偿处理
七、生产环境消息不丢失完整配置清单(直接复制)
7.1 YML 核心配置
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
# 生产者确认
publisher-confirm-type: correlated
publisher-returns: true
template:
mandatory: true
# 消费者手动确认
listener:
simple:
acknowledge-mode: manual
retry:
enabled: true # 开启重试
7.2 代码必须遵守
八、总结:一张表记住所有防丢失方案
| 生产者 | Confirm 确认 + Return 回退 | 确保消息一定到达 MQ |
| MQ 服务端 | 交换机+队列+消息 持久化 | 宕机重启不丢失 |
| 消费者 | 手动 ACK 确认 | 处理完成再删除 |
| 兜底 | 死信队列 DLX | 失败消息不丢弃 |
九、全文总结
确保 RabbitMQ 消息不丢失的核心口诀:
只要严格按照上述全链路方案配置,就能保证 RabbitMQ 在网络波动、服务宕机、异常报错等极端情况下,消息绝对不会丢失!
文末说明
本文是 RabbitMQ 生产实战核心文章,解决了线上最关键的可靠性问题。后续将更新《RabbitMQ 消息重复消费与幂等性解决方案》《RabbitMQ 高可用集群搭建》,欢迎点赞、收藏、关注!

|
🌺The End🌺点点关注,收藏不迷路🌺 |




