<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Redis MQ on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/redis-mq/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Tue, 30 Jun 2020 10:00:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/redis-mq/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>消息队列总结：RabbitMQ、Kafka、RocketMQ 与 Redis MQ 选型对比与实践避坑</title>
      <link>https://ftmao.com/blog/posts/mq-comparison-rabbitmq-kafka-rocketmq/</link>
      <pubDate>Tue, 30 Jun 2020 10:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/mq-comparison-rabbitmq-kafka-rocketmq/</guid>
      <description>&lt;h1 id=&#34;消息队列总结rabbitmqkafkarocketmq-与-redis-mq-选型对比与实践避坑&#34;&gt;消息队列总结：RabbitMQ、Kafka、RocketMQ 与 Redis MQ 选型对比与实践避坑&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;消息队列是分布式系统里最常见的「异步管道」。这篇笔记把 RabbitMQ、Kafka、RocketMQ 和 Redis MQ 放在一起比较，重点回答：什么时候该用哪个？推和拉到底怎么选？长连接有什么影响？以及实际使用中的避坑和异常处理经验。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一为什么需要消息队列&#34;&gt;一、为什么需要消息队列？&lt;/h2&gt;
&lt;p&gt;在没有 MQ 的系统中，A 服务调用 B 服务通常是同步的：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A ──同步调用──▶ B ──同步调用──▶ C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     等待返回      等待返回&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;链路越长，响应越慢，容错越差。MQ 的核心价值是把「同步依赖」变成「异步管道」：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A ──发送消息──▶ MQ ──接收消息──▶ B
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   立即返回         异步处理&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;11-mq-解决的三大问题&#34;&gt;1.1 MQ 解决的三大问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;解耦&lt;/strong&gt;：生产方只负责发消息，不用关心谁消费、怎么消费。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步&lt;/strong&gt;：把非核心链路（发短信、记日志、发券）从主流程剥离，降低接口 RT。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;削峰填谷&lt;/strong&gt;：突发流量先写入队列，下游按自身能力消费，避免被压垮。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;12-什么时候必须引入-mq&#34;&gt;1.2 什么时候必须引入 MQ？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;上下游处理速度差异大，同步调用会导致阻塞或超时。&lt;/li&gt;
&lt;li&gt;需要保证某些操作最终执行，但不需要实时返回结果。&lt;/li&gt;
&lt;li&gt;系统拆分后，多个服务需要感知同一事件。&lt;/li&gt;
&lt;li&gt;大促/活动场景下，需要缓冲突发流量。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二四种-mq-横向对比&#34;&gt;二、四种 MQ 横向对比&lt;/h2&gt;
&lt;p&gt;RabbitMQ、Kafka、RocketMQ 是主流企业级 MQ，Redis 也能当轻量 MQ 用，但定位不同。&lt;/p&gt;
&lt;h3 id=&#34;21-核心定位&#34;&gt;2.1 核心定位&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;RocketMQ&lt;/th&gt;
					&lt;th&gt;RabbitMQ&lt;/th&gt;
					&lt;th&gt;Kafka&lt;/th&gt;
					&lt;th&gt;Redis MQ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;出身与设计目标&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;阿里开源，面向在线交易/金融级消息&lt;/td&gt;
					&lt;td&gt;Erlang 实现，面向通用企业消息&lt;/td&gt;
					&lt;td&gt;LinkedIn 开源，面向日志采集与流处理&lt;/td&gt;
					&lt;td&gt;内存数据库，轻量级队列/发布订阅&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;数据模型&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Topic + Queue，支持 Tag 过滤&lt;/td&gt;
					&lt;td&gt;Exchange + Queue，路由灵活&lt;/td&gt;
					&lt;td&gt;Topic + Partition，分区有序&lt;/td&gt;
					&lt;td&gt;List / Stream / PubSub&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;默认消费方式&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Push（长轮询封装）+ Pull&lt;/td&gt;
					&lt;td&gt;Push（AMQP 推送）&lt;/td&gt;
					&lt;td&gt;Pull（消费者主动拉取）&lt;/td&gt;
					&lt;td&gt;Push（PubSub）/ Pull（BLPOP）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;顺序消息&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;分片内有序，Sharding Key 控制&lt;/td&gt;
					&lt;td&gt;单 Queue 有序&lt;/td&gt;
					&lt;td&gt;Partition 内有序&lt;/td&gt;
					&lt;td&gt;单 Stream/列表有序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;延迟消息&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;原生支持 18 个级别&lt;/td&gt;
					&lt;td&gt;需插件或死信实现&lt;/td&gt;
					&lt;td&gt;不原生支持，需借助外部组件&lt;/td&gt;
					&lt;td&gt;无原生支持&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;事务消息&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;原生支持&lt;/td&gt;
					&lt;td&gt;不支持原生事务消息&lt;/td&gt;
					&lt;td&gt;不支持原生事务消息&lt;/td&gt;
					&lt;td&gt;不支持&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消息持久化&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;磁盘持久化，支持同步/异步刷盘&lt;/td&gt;
					&lt;td&gt;磁盘持久化&lt;/td&gt;
					&lt;td&gt;磁盘持久化，顺序写&lt;/td&gt;
					&lt;td&gt;默认内存，可持久化但非强项&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消息轨迹&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;原生支持&lt;/td&gt;
					&lt;td&gt;需额外配置&lt;/td&gt;
					&lt;td&gt;需额外组件&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;22-性能对比&#34;&gt;2.2 性能对比&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;RocketMQ&lt;/th&gt;
					&lt;th&gt;RabbitMQ&lt;/th&gt;
					&lt;th&gt;Kafka&lt;/th&gt;
					&lt;th&gt;Redis MQ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;单机吞吐&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;10 万级 TPS&lt;/td&gt;
					&lt;td&gt;万级 TPS&lt;/td&gt;
					&lt;td&gt;百万级 TPS（批量场景）&lt;/td&gt;
					&lt;td&gt;十万级 TPS（内存操作）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;延迟&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;毫秒级&lt;/td&gt;
					&lt;td&gt;微秒-毫秒级&lt;/td&gt;
					&lt;td&gt;毫秒级，批量时更高&lt;/td&gt;
					&lt;td&gt;微秒-毫秒级&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消息堆积能力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;强，适合削峰&lt;/td&gt;
					&lt;td&gt;一般，堆积过多影响性能&lt;/td&gt;
					&lt;td&gt;极强，专为日志设计&lt;/td&gt;
					&lt;td&gt;弱，内存容量受限&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;批量效率&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;中等&lt;/td&gt;
					&lt;td&gt;一般&lt;/td&gt;
					&lt;td&gt;极高&lt;/td&gt;
					&lt;td&gt;一般&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kafka 吞吐数字通常来自批量、压缩、顺序写的日志场景；单条小消息低延迟不如 RocketMQ。&lt;/li&gt;
&lt;li&gt;RabbitMQ 延迟低，但高吞吐和海量堆积不是强项。&lt;/li&gt;
&lt;li&gt;RocketMQ 在「中等吞吐 + 低延迟 + 强堆积」之间取得了较好平衡。&lt;/li&gt;
&lt;li&gt;Redis MQ 性能高，但消息堆积、持久化、事务、延迟消息都不完善，适合轻量、临时场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;23-成本与生态&#34;&gt;2.3 成本与生态&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;RocketMQ&lt;/th&gt;
					&lt;th&gt;RabbitMQ&lt;/th&gt;
					&lt;th&gt;Kafka&lt;/th&gt;
					&lt;th&gt;Redis MQ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;部署复杂度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;中等（NameServer + Broker）&lt;/td&gt;
					&lt;td&gt;低（单节点即可运行）&lt;/td&gt;
					&lt;td&gt;高（ZooKeeper/KRaft + Broker）&lt;/td&gt;
					&lt;td&gt;低（Redis 单实例/集群）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;运维成本&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;中等，阿里系文档丰富&lt;/td&gt;
					&lt;td&gt;低，但 Erlang 问题排查门槛高&lt;/td&gt;
					&lt;td&gt;高，调优项多&lt;/td&gt;
					&lt;td&gt;低，Redis 团队普遍熟悉&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;云服务成熟度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;阿里云 RocketMQ 成熟&lt;/td&gt;
					&lt;td&gt;各云厂商都有托管版&lt;/td&gt;
					&lt;td&gt;各云厂商 Kafka 托管版成熟&lt;/td&gt;
					&lt;td&gt;云 Redis 托管版成熟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;学习曲线&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;中等&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;大数据生态&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;一般，可与 Flink/Spark 对接&lt;/td&gt;
					&lt;td&gt;弱&lt;/td&gt;
					&lt;td&gt;极强，流处理事实标准&lt;/td&gt;
					&lt;td&gt;弱&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;语言客户端&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Java 最完善，其他语言有社区版&lt;/td&gt;
					&lt;td&gt;极其丰富&lt;/td&gt;
					&lt;td&gt;极其丰富&lt;/td&gt;
					&lt;td&gt;极其丰富&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;24-适用场景推荐&#34;&gt;2.4 适用场景推荐&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;推荐&lt;/th&gt;
					&lt;th&gt;原因&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;电商/金融订单、交易消息&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;延迟低、事务消息、顺序消息、监控完善&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;异步任务、分布式 Worker、视频渲染&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;PushConsumer 自动负载均衡，失败重试完善&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;传统企业应用、RPC 解耦、路由复杂&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;简单易用，Exchange 路由灵活，快速上线&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;日志采集、埋点、实时数仓、流处理&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;吞吐和生态碾压，分区模型适合流计算&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;事件总线、多语言异构系统&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ / Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;客户端生态更丰富&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;需要事务消息且不想自己实现&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;原生事务消息是差异化能力&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;轻量异步通知、缓存队列、临时任务&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;部署简单、延迟低，但不要把核心交易交给它&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;已有 Redis 基础设施，不想引入新组件&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;作为过渡方案或辅助队列可用&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;25-一句话选型&#34;&gt;2.5 一句话选型&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;可靠交易、事务消息、顺序消息、在线业务  →  RocketMQ
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;快速搭建、路由灵活、团队规模小          →  RabbitMQ
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;日志/流处理/大数据管道、吞吐优先          →  Kafka
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;轻量通知、临时队列、已有 Redis 生态       →  Redis MQ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;很多大厂内部是「Kafka 做日志流 + RocketMQ 做业务消息 + RabbitMQ 做轻量任务 + Redis 做缓存/通知」组合使用，不是单选题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三底层架构与核心差异&#34;&gt;三、底层架构与核心差异&lt;/h2&gt;
&lt;h3 id=&#34;31-四种-mq-架构对比&#34;&gt;3.1 四种 MQ 架构对比&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph RocketMQ
        P1[Producer] --&amp;gt; NS[NameServer]
        NS --&amp;gt; B1[Broker Master]
        B1 --&amp;gt; B2[Broker Slave]
        B1 --&amp;gt; C1[Consumer]
    end

    subgraph Kafka
        P2[Producer] --&amp;gt; KZ[ZooKeeper / KRaft]
        KZ --&amp;gt; KB1[Broker 1]
        KZ --&amp;gt; KB2[Broker 2]
        KB1 --&amp;gt; C2[Consumer]
    end

    subgraph RabbitMQ
        P3[Producer] --&amp;gt; EX[Exchange]
        EX --&amp;gt; Q1[Queue A]
        EX --&amp;gt; Q2[Queue B]
        Q1 --&amp;gt; C3[Consumer A]
        Q2 --&amp;gt; C4[Consumer B]
    end

    subgraph RedisMQ
        P4[Producer] --&amp;gt; R[(Redis)]
        R --&amp;gt; C5[Consumer BLPOP]
        R --&amp;gt; C6[Subscriber]
    end&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;32-存储模型&#34;&gt;3.2 存储模型&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;产品&lt;/th&gt;
					&lt;th&gt;存储结构&lt;/th&gt;
					&lt;th&gt;核心特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;CommitLog + ConsumeQueue&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;所有 Topic 的消息顺序写入同一个 CommitLog，再用 ConsumeQueue 存每个 Queue 的偏移索引。顺序写磁盘，I/O 效率高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Partition Segment + Index&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每个 Partition 是独立日志目录，顺序写入 Segment，配合稀疏索引。Partition 间物理隔离。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Queue 独立存储&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每个 Queue 维护独立索引和存储，Queue 越多元数据开销越大。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内存 List / Stream&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基于内存操作，速度快，但容量受内存限制，持久化可靠性不如专业 MQ。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    subgraph RocketMQ_Storage[&amp;#34;RocketMQ 存储模型&amp;#34;]
        CL[CommitLog&amp;lt;br/&amp;gt;所有消息顺序写]
        CQ1[ConsumeQueue A&amp;lt;br/&amp;gt;偏移索引]
        CQ2[ConsumeQueue B&amp;lt;br/&amp;gt;偏移索引]
        CL --&amp;gt; CQ1
        CL --&amp;gt; CQ2
    end

    subgraph Kafka_Storage[&amp;#34;Kafka 存储模型&amp;#34;]
        KP1[TopicA-P0 Log&amp;lt;br/&amp;gt;独立 Partition]
        KP2[TopicA-P1 Log&amp;lt;br/&amp;gt;独立 Partition]
    end

    subgraph RabbitMQ_Storage[&amp;#34;RabbitMQ 存储模型&amp;#34;]
        MQ1[Queue A&amp;lt;br/&amp;gt;独立索引]
        MQ2[Queue B&amp;lt;br/&amp;gt;独立索引]
    end&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;33-路由与元数据管理&#34;&gt;3.3 路由与元数据管理&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;产品&lt;/th&gt;
					&lt;th&gt;注册/路由中心&lt;/th&gt;
					&lt;th&gt;设计哲学&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;NameServer&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无状态集群，Broker 主动上报路由，Producer/Consumer 定时拉取。最终一致，轻量。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;ZooKeeper / KRaft&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;老版本依赖 ZooKeeper 存元数据、选 Controller；新版本用 KRaft 自洽协议。强一致要求更高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内置 Mnesia 数据库&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;集群节点共享元数据，Erlang 进程模型天然分布式，但集群扩展性相对有限。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;无&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;依赖 Redis 自身的 Cluster/哨兵做高可用，没有独立路由层。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;34-复制与高可用&#34;&gt;3.4 复制与高可用&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;产品&lt;/th&gt;
					&lt;th&gt;复制方式&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Master-Slave 同步/异步复制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;同步复制保证不丢消息，异步复制性能更高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Partition 多副本 + ISR 机制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自动 Failover，成熟度高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;普通队列 + 镜像队列&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;普通队列只存在于一个节点；镜像队列复制到多个节点但吞吐下降。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;主从 + 哨兵 / Cluster&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Redis 自身的高可用机制，不是为消息队列专门设计。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四推拉模式与长连接&#34;&gt;四、推、拉模式与长连接&lt;/h2&gt;
&lt;h3 id=&#34;41-push-vs-pull-对比&#34;&gt;4.1 Push vs Pull 对比&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Push（推）&lt;/th&gt;
					&lt;th&gt;Pull（拉）&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;控制权&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;在 Broker&lt;/td&gt;
					&lt;td&gt;在 Consumer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;实时性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高，Broker 有消息就发&lt;/td&gt;
					&lt;td&gt;依赖拉取间隔，实时性可调&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;背压能力&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;较弱，Consumer 处理慢会堆积&lt;/td&gt;
					&lt;td&gt;强，Consumer 自己控制速率&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;实现复杂度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;低，业务写回调即可&lt;/td&gt;
					&lt;td&gt;高，需自管 offset、拉取循环&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;实时性要求高、消费轻量&lt;/td&gt;
					&lt;td&gt;批量处理、消费重、需要控速&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;42-四种-mq-的推拉实现&#34;&gt;4.2 四种 MQ 的推拉实现&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;产品&lt;/th&gt;
					&lt;th&gt;消费方式&lt;/th&gt;
					&lt;th&gt;是否长连接&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;长轮询 Pull 封装成 Push&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;Consumer 与 Broker 保持长连接，Broker hold 请求 5 秒左右，有新消息立即返回。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;消费者主动 Pull&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;否（可保持连接但非必需）&lt;/td&gt;
					&lt;td&gt;Consumer 自己决定何时拉、拉多少，灵活性最高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Broker 真 Push（AMQP）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;Channel 长连接，Broker 把消息塞给 Consumer，处理完 ACK。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;PubSub 推 / BLPOP 拉&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;PubSub 是长连接推送；BLPOP 是阻塞拉取，也算长连接。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;43-长连接的影响&#34;&gt;4.3 长连接的影响&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 长连接优势
        A1[低延迟]
        A2[实时推送]
        A3[减少建连开销]
    end

    subgraph 长连接代价
        B1[连接数消耗大]
        B2[需要心跳保活]
        B3[网络断开感知延迟]
        B4[Consumer 慢会拖垮 Broker]
    end&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;长连接的好处&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;消息到达可以立刻推送给 Consumer，延迟低。&lt;/li&gt;
&lt;li&gt;避免频繁建立/断开 TCP 连接的开销。&lt;/li&gt;
&lt;li&gt;适合在线业务、实时通知类场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;长连接的代价&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Broker 需要维护大量连接，连接数成为重要资源。&lt;/li&gt;
&lt;li&gt;必须有心跳机制，否则无法及时发现 Consumer 宕机。&lt;/li&gt;
&lt;li&gt;Consumer 处理慢时，消息会堆积在 Broker 内存或磁盘，容易把 Broker 压垮。&lt;/li&gt;
&lt;li&gt;网络闪断后需要重连、重平衡，可能带来消费抖动。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;44-选择原则&#34;&gt;4.4 选择原则&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[选择消费模式] --&amp;gt; B{实时性要求高?}
    B --&amp;gt;|是| C{消费逻辑轻量?}
    B --&amp;gt;|否| D[Pull 模式]
    C --&amp;gt;|是| E[Push 模式]
    C --&amp;gt;|否| F[Pull 模式 或 限流 Push]
    D --&amp;gt; G[批量处理/ETL/数据同步]
    E --&amp;gt; H[在线业务/实时通知]
    F --&amp;gt; I[重任务/视频渲染/大数据]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;五使用注意点与避坑指南&#34;&gt;五、使用注意点与避坑指南&lt;/h2&gt;
&lt;h3 id=&#34;51-rocketmq-避坑&#34;&gt;5.1 RocketMQ 避坑&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;解决&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消费组订阅不一致&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;同一个 ConsumerGroup 订阅不同 Topic/Tag，重平衡混乱&lt;/td&gt;
					&lt;td&gt;一个 ConsumerGroup 只订阅一个 Topic + 一套 Tag&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Tag 用得太细&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;管理混乱，消费者过滤复杂&lt;/td&gt;
					&lt;td&gt;Topic 按业务域划分，Tag 做粗粒度过滤&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消息体过大&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;超过 4MB 默认限制，发送失败&lt;/td&gt;
					&lt;td&gt;消息体只传 ID 和必要字段，完整数据从 DB/OSS 拉取&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;顺序消息误用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;全局顺序严重拖垮吞吐&lt;/td&gt;
					&lt;td&gt;只在真正需要局部顺序的场景用 Sharding Key&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;NameServer 路由延迟&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Broker 扩缩容后发送到已下线节点&lt;/td&gt;
					&lt;td&gt;理解最终一致性，扩缩容留足等待时间&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;自动创建 Topic&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;生产环境订阅失败或路由错误&lt;/td&gt;
					&lt;td&gt;提前创建 Topic 和 ConsumerGroup&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;52-kafka-避坑&#34;&gt;5.2 Kafka 避坑&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;解决&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Partition 数设置不当&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;太少并行度不够，太多元数据压力大&lt;/td&gt;
					&lt;td&gt;根据吞吐和 Consumer 数合理规划&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;消费者 Rebalance 频繁&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;消费停滞，组员加入/退出频繁&lt;/td&gt;
					&lt;td&gt;避免频繁扩缩容，调整 session.timeout.ms&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Offset 提交策略不当&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;重复消费或消息丢失&lt;/td&gt;
					&lt;td&gt;重要消息手动提交，处理完再 commit&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Producer  acks=0/1&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;丢消息&lt;/td&gt;
					&lt;td&gt;关键业务用 acks=all&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;单 Partition 热点&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;某个 Partition 消费滞后&lt;/td&gt;
					&lt;td&gt;合理设计 Key，避免 Key 倾斜&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;53-rabbitmq-避坑&#34;&gt;5.3 RabbitMQ 避坑&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;解决&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;镜像队列性能下降&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;开镜像后吞吐明显降低&lt;/td&gt;
					&lt;td&gt;只对关键队列开镜像&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;队列堆积过多&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Broker 内存/磁盘告警，性能下降&lt;/td&gt;
					&lt;td&gt;控制生产速度，及时扩容 Consumer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ACK 模式用错&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;消息丢失或重复&lt;/td&gt;
					&lt;td&gt;手动 ACK，处理完再确认&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Exchange 路由复杂&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;消息去向难以追踪&lt;/td&gt;
					&lt;td&gt;规范命名，做好监控&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Connection/Channel 滥用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;连接数耗尽&lt;/td&gt;
					&lt;td&gt;Channel 复用，避免每个消息新建连接&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;54-redis-mq-避坑&#34;&gt;5.4 Redis MQ 避坑&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;解决&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;PubSub 消息丢失&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Consumer 断线期间的消息收不到&lt;/td&gt;
					&lt;td&gt;重要消息用 Stream 或专业 MQ&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;List 做队列无 ACK&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Consumer 处理失败消息丢失&lt;/td&gt;
					&lt;td&gt;用 Stream 的 ACK 机制&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;内存不足&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Redis OOM&lt;/td&gt;
					&lt;td&gt;设置合理过期时间，控制队列长度&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;把 Redis 当核心 MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据丢失、无事务、无延迟消息&lt;/td&gt;
					&lt;td&gt;核心交易链路用 RocketMQ/Kafka&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;55-通用最佳实践&#34;&gt;5.5 通用最佳实践&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;消息体尽量小&lt;/strong&gt;：传 ID 不传大对象。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;幂等设计&lt;/strong&gt;：所有 Consumer 都要做幂等，MQ 只保证至少一次投递。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控到位&lt;/strong&gt;：堆积量、消费 TPS、延迟、死信队列、Broker 资源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;版本一致&lt;/strong&gt;：服务端和客户端版本不要差距太大。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提前创建资源&lt;/strong&gt;：生产环境不要依赖自动创建 Topic/Queue。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;区分可重试与不可重试异常&lt;/strong&gt;：网络抖动可以重试，参数错误直接进死信。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六异常场景处理分-mq-说明&#34;&gt;六、异常场景处理（分 MQ 说明）&lt;/h2&gt;
&lt;p&gt;下面列出的异常场景在 RocketMQ、RabbitMQ、Kafka、Redis MQ 中都会遇到，但每种 MQ 提供的机制和最佳实践不同。这一节把四种 MQ 放在一起对比说明。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    P[Producer 发送层] --&amp;gt;|发送失败/超时| B[Broker 存储层]
    B --&amp;gt;|刷盘/复制失败| C[Consumer 消费层]
    C --&amp;gt;|重复/失败/卡住| Biz[业务异常兜底]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;61-消息丢失各-mq-如何防范&#34;&gt;6.1 消息丢失：各 MQ 如何防范&lt;/h3&gt;
&lt;p&gt;消息丢失通常发生在三个环节：&lt;strong&gt;Producer 发送失败&lt;/strong&gt;、&lt;strong&gt;Broker 存储失败&lt;/strong&gt;、&lt;strong&gt;Consumer 消费失败未 ACK&lt;/strong&gt;。四种 MQ 的防范方式如下：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;环节&lt;/th&gt;
					&lt;th&gt;RocketMQ&lt;/th&gt;
					&lt;th&gt;RabbitMQ&lt;/th&gt;
					&lt;th&gt;Kafka&lt;/th&gt;
					&lt;th&gt;Redis MQ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Producer 发送&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;同步发送 &lt;code&gt;SYNC&lt;/code&gt; + 失败重试；避免 &lt;code&gt;ONEWAY&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;使用 &lt;code&gt;confirm&lt;/code&gt; 模式等待 Broker ACK；开启 Publisher Confirms&lt;/td&gt;
					&lt;td&gt;设置 &lt;code&gt;acks=all&lt;/code&gt; + 重试；避免 &lt;code&gt;acks=0/1&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;无发送确认机制，调用成功不代表持久化成功；重要消息不要用 Redis PubSub&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Broker 存储&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;同步刷盘 &lt;code&gt;SYNC_FLUSH&lt;/code&gt; + 同步复制 &lt;code&gt;SYNC_MASTER&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;队列持久化 + 镜像队列复制；消息标记 &lt;code&gt;persistent&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;replication.factor &amp;gt;= 3&lt;/code&gt; + &lt;code&gt;min.insync.replicas&lt;/code&gt; 控制&lt;/td&gt;
					&lt;td&gt;AOF/ RDB 持久化，但默认异步；主从切换可能丢数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Consumer 消费&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;先处理业务再返回 &lt;code&gt;CONSUME_SUCCESS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;手动 ACK，处理完再 &lt;code&gt;basic.ack&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;处理完再 commit offset&lt;/td&gt;
					&lt;td&gt;Stream 用 &lt;code&gt;XACK&lt;/code&gt; 确认；List/ PubSub 无 ACK&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;兜底&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;业务对账 + 补偿表&lt;/td&gt;
					&lt;td&gt;业务对账 + 补偿表&lt;/td&gt;
					&lt;td&gt;业务对账 + 补偿表&lt;/td&gt;
					&lt;td&gt;不建议做核心兜底，Redis 本身不是可靠 MQ&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键提醒&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;：&lt;code&gt;SYNC_MASTER&lt;/code&gt; + &lt;code&gt;SYNC_FLUSH&lt;/code&gt; 配置最安全，但性能最低；在线交易通常用 &lt;code&gt;SYNC_MASTER&lt;/code&gt; + &lt;code&gt;ASYNC_FLUSH&lt;/code&gt; 折中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;：默认自动 ACK 最容易丢消息，生产环境一定要改手动 ACK。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kafka&lt;/strong&gt;：&lt;code&gt;acks=all&lt;/code&gt; 配合 &lt;code&gt;min.insync.replicas&lt;/code&gt; 才能保证写入 ISR 多数副本；只配置 &lt;code&gt;acks=all&lt;/code&gt; 不够。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;：Redis 本身不是为消息可靠性设计的，&lt;strong&gt;不要把核心交易消息的防丢失交给 Redis&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;62-消息重复各-mq-的投递语义与幂等&#34;&gt;6.2 消息重复：各 MQ 的投递语义与幂等&lt;/h3&gt;
&lt;p&gt;四种 MQ 大多只保证「至少一次投递」（at-least-once），重复消费要靠业务层幂等。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MQ&lt;/th&gt;
					&lt;th&gt;默认投递语义&lt;/th&gt;
					&lt;th&gt;重复来源&lt;/th&gt;
					&lt;th&gt;推荐幂等方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;At-least-once&lt;/td&gt;
					&lt;td&gt;网络超时重发、Consumer 重启、Broker 重试&lt;/td&gt;
					&lt;td&gt;消息 &lt;code&gt;keys&lt;/code&gt; 做唯一业务 Key + 数据库唯一索引&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;At-least-once&lt;/td&gt;
					&lt;td&gt;连接断开、ACK 未到达 Broker、Consumer 重启&lt;/td&gt;
					&lt;td&gt;消息 &lt;code&gt;message_id&lt;/code&gt; 或业务 Key + 幂等表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;At-least-once&lt;/td&gt;
					&lt;td&gt;Consumer Rebalance、Offset 提交失败、Producer 重试&lt;/td&gt;
					&lt;td&gt;业务 Key 去重；Kafka 幂等 Producer 只能去重单会话内重复&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;不保证&lt;/td&gt;
					&lt;td&gt;PubSub 不持久化，断线即丢；Stream 相对可靠但无原生重试&lt;/td&gt;
					&lt;td&gt;业务侧用 Redis &lt;code&gt;SETNX&lt;/code&gt; 或数据库唯一索引&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 通用幂等伪代码，适用于四种 MQ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;consume&lt;/span&gt;(msg):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    biz_key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; extract_biz_key(msg)  &lt;span style=&#34;color:#75715e&#34;&gt;# RocketMQ keys / RabbitMQ message_id / Kafka key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        idempotent_record&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;insert(biz_key&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;biz_key, status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;processing&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; UniqueViolation:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; SUCCESS  &lt;span style=&#34;color:#75715e&#34;&gt;# 已处理过，直接成功&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        do_business(msg)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        idempotent_record&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;update(biz_key, status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;done&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; SUCCESS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; RetryableException:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        idempotent_record&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;update(biz_key, status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; RETRY
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; NonRetryableException:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        idempotent_record&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;update(biz_key, status&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; DEAD_LETTER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;63-消费失败重试与死信机制&#34;&gt;6.3 消费失败：重试与死信机制&lt;/h3&gt;
&lt;p&gt;消费失败后，不同 MQ 的重试和死信（DLQ）机制差异很大：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MQ&lt;/th&gt;
					&lt;th&gt;重试机制&lt;/th&gt;
					&lt;th&gt;死信队列&lt;/th&gt;
					&lt;th&gt;注意事项&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;默认最多 16 次，间隔阶梯递增（10s、30s、1m&amp;hellip;）&lt;/td&gt;
					&lt;td&gt;自动进入 &lt;code&gt;%DLQ%consumer_group&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;可区分 &lt;code&gt;RECONSUME_LATER&lt;/code&gt; 重试和直接成功；重试次数可在 Broker 配置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无内置重试，需业务侧或插件实现；常用 TTL + 死信交换器（DLX）做延迟重试&lt;/td&gt;
					&lt;td&gt;通过 &lt;code&gt;x-dead-letter-exchange&lt;/code&gt; 配置 DLX/DLQ&lt;/td&gt;
					&lt;td&gt;手动 ACK 失败或 NACK + requeue=false 进入死信&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无内置重试次数，失败时 Consumer 自己决定是否重试或跳过&lt;/td&gt;
					&lt;td&gt;无原生 DLQ，需业务侧或 Kafka Connect 实现&lt;/td&gt;
					&lt;td&gt;常见做法：失败消息写入专用 Error Topic，由补偿服务处理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;无内置重试&lt;/td&gt;
					&lt;td&gt;无原生 DLQ&lt;/td&gt;
					&lt;td&gt;Stream 可配合 Consumer Group 的 Pending List 人工处理；List/ PubSub 无重试能力&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[Consumer 处理失败] --&amp;gt; B{MQ 类型}
    B --&amp;gt;|RocketMQ| C[返回 RECONSUME_LATER]
    B --&amp;gt;|RabbitMQ| D[NACK + requeue=false 进 DLX]
    B --&amp;gt;|Kafka| E[写入 Error Topic 或暂停消费]
    B --&amp;gt;|Redis Stream| F[XCLAIM 或人工处理 Pending]
    C --&amp;gt; G{重试超限?}
    G --&amp;gt;|是| H[进入 DLQ]
    G --&amp;gt;|否| C
    D --&amp;gt; H
    E --&amp;gt; I[补偿服务消费 Error Topic]
    F --&amp;gt; J[业务侧补偿]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;可重试异常&lt;/strong&gt;：网络超时、依赖服务短暂不可用、数据库连接池耗尽。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不可重试异常&lt;/strong&gt;：参数非法、依赖返回 4xx、业务规则冲突、数据不存在。&lt;/p&gt;
&lt;h3 id=&#34;64-业务异常处理&#34;&gt;6.4 业务异常处理&lt;/h3&gt;
&lt;p&gt;业务异常（如参数错误、状态冲突、规则校验失败）和系统异常（网络、DB、依赖故障）要分开处理。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[Consumer 捕获异常] --&amp;gt; B{异常类型}
    B --&amp;gt;|系统异常&amp;lt;br/&amp;gt;网络/DB/依赖| C[MQ 重试]
    B --&amp;gt;|业务异常&amp;lt;br/&amp;gt;参数/规则/状态冲突| D[记录失败明细]
    D --&amp;gt; E{能否修复?}
    E --&amp;gt;|能| F[人工补偿/修复后重投]
    E --&amp;gt;|不能| G[进死信队列或丢弃]
    C --&amp;gt; H{重试成功?}
    H --&amp;gt;|否| I[进入死信/Error Topic]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MQ&lt;/th&gt;
					&lt;th&gt;业务异常处理建议&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;捕获业务异常后，直接返回 &lt;code&gt;CONSUME_SUCCESS&lt;/code&gt; 并记录失败原因，避免无意义重试；或主动放入自定义补偿 Topic。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;业务异常时 &lt;code&gt;basic.nack(requeue=false)&lt;/code&gt; 直接进死信，不要在 RabbitMQ 里反复重试业务错误。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;业务异常写入 Error Topic，由补偿服务按业务规则处理；Consumer 继续消费后续消息，避免阻塞 Partition。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Redis 不适合复杂异常处理；业务异常建议直接记录到数据库或日志，人工介入。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;业务异常兜底策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;记录失败明细&lt;/strong&gt;：消息内容、异常原因、时间、Consumer 实例、业务 Key。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人工补偿平台&lt;/strong&gt;：按业务 Key 重投、跳过、标记已处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态机兜底&lt;/strong&gt;：订单等核心业务要有最终一致性校验。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;告警分级&lt;/strong&gt;：死信队列增长、消费停滞、重试频繁分级告警。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要无限重试业务异常&lt;/strong&gt;：参数错误重试 16 次没有意义。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;65-消息卡住消费停滞&#34;&gt;6.5 消息卡住/消费停滞&lt;/h3&gt;
&lt;p&gt;消费停滞是四种 MQ 都会遇到的异常，但原因和处理方式各有侧重：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MQ&lt;/th&gt;
					&lt;th&gt;常见原因&lt;/th&gt;
					&lt;th&gt;处理手段&lt;/th&gt;
					&lt;th&gt;监控指标&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Consumer 实例少、单条处理慢、Consumer 宕机、下游依赖慢&lt;/td&gt;
					&lt;td&gt;扩容 Consumer（不超过 Queue 数）、优化消费逻辑、限流、降级&lt;/td&gt;
					&lt;td&gt;ConsumeProgress 堆积量、消费 TPS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;队列堆积导致内存/磁盘告警、Consumer 连接断开、Channel 阻塞&lt;/td&gt;
					&lt;td&gt;扩容 Consumer、控制生产速度、启用队列长度限制&lt;/td&gt;
					&lt;td&gt;Queue 深度、内存使用率、磁盘告警&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Partition 消费滞后、Consumer Rebalance 频繁、单 Partition 热点&lt;/td&gt;
					&lt;td&gt;增加 Partition、优化 Key 设计、调整 &lt;code&gt;session.timeout.ms&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Consumer Lag、Rebalance 频率&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内存不足、Consumer 断线（PubSub 丢消息）、处理慢&lt;/td&gt;
					&lt;td&gt;控制队列长度、设置过期时间、用 Stream 替代 PubSub&lt;/td&gt;
					&lt;td&gt;Redis 内存、Pending List 长度&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[消息堆积] --&amp;gt; B{原因}
    B --&amp;gt;|Consumer 少| C[扩容 Consumer]
    B --&amp;gt;|单条处理慢| D[优化消费逻辑/异步化]
    B --&amp;gt;|Consumer 宕机| E[心跳超时触发重平衡]
    B --&amp;gt;|下游依赖慢| F[限流/降级/异步处理]
    B --&amp;gt;|Partition/Queue 热点| G[调整 Key 或增加分区]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;66-顺序消息异常&#34;&gt;6.6 顺序消息异常&lt;/h3&gt;
&lt;p&gt;顺序消息一旦某条处理卡住，后续消息都会被阻塞，四种 MQ 的处理方式不同：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MQ&lt;/th&gt;
					&lt;th&gt;顺序模型&lt;/th&gt;
					&lt;th&gt;异常影响&lt;/th&gt;
					&lt;th&gt;处理建议&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RocketMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Sharding Key 路由到同一 MessageQueue，单线程消费&lt;/td&gt;
					&lt;td&gt;一条失败会阻塞整个 Queue 的后续消息&lt;/td&gt;
					&lt;td&gt;设置消费超时；失败次数过多时考虑跳过或转移；业务上保证单条处理轻量&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RabbitMQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;单 Queue 天然有序，单 Consumer 单线程消费&lt;/td&gt;
					&lt;td&gt;一个 Consumer 卡住会阻塞整个 Queue&lt;/td&gt;
					&lt;td&gt;控制单条处理时间；必要时拆分多个 Queue 做局部顺序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;同一 Partition 内有序，单 Consumer 消费 Partition&lt;/td&gt;
					&lt;td&gt;一条消息处理慢会阻塞整个 Partition&lt;/td&gt;
					&lt;td&gt;合理设计 Key，避免单个 Partition 成为热点；业务异常时写入 Error Topic 避免阻塞&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Redis MQ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Stream/ List 单节点内有序&lt;/td&gt;
					&lt;td&gt;单 Consumer 卡住会阻塞后续消费&lt;/td&gt;
					&lt;td&gt;不建议用 Redis 做强顺序消息；处理异常时直接记录并人工处理&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[Queue/Partition 内顺序消费] --&amp;gt; B[消息 1 处理失败或超慢]
    B --&amp;gt; C[消息 2 等待]
    C --&amp;gt; D[消息 3 等待]
    B --&amp;gt; E{如何处理?}
    E --&amp;gt;|跳过| F[破坏顺序性]
    E --&amp;gt;|重试| G[阻塞后续消息]
    E --&amp;gt;|转移| H[进死信/Error Topic]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;顺序消息异常处理原则&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只在真正需要顺序的场景使用顺序消息。&lt;/li&gt;
&lt;li&gt;单条消息处理要轻量，避免长耗时阻塞队列。&lt;/li&gt;
&lt;li&gt;业务上设计「局部顺序」而不是「全局顺序」。&lt;/li&gt;
&lt;li&gt;顺序消息失败时，优先考虑业务补偿，而不是无限重试或简单跳过。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七总结&#34;&gt;七、总结&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;选型不是单选题&lt;/strong&gt;：RocketMQ 适合在线业务，Kafka 适合日志/流处理，RabbitMQ 适合轻量快速落地，Redis MQ 适合轻量辅助场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推/拉不是对立关系&lt;/strong&gt;：RocketMQ 的 Push 底层是长轮询 Pull；RabbitMQ 是真 Push；Kafka 是真 Pull。选择看「谁来控制消费节奏」。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长连接是双刃剑&lt;/strong&gt;：实时性好，但连接维护、背压、心跳都要考虑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异常处理要分层&lt;/strong&gt;：发送层确认、Broker 层持久化、消费层幂等 + 重试 + 死信。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;业务异常要兜底&lt;/strong&gt;：区分可重试与不可重试，建立补偿机制和人工介入平台。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避坑靠规范&lt;/strong&gt;：订阅一致、消息体小、顺序消息慎用、监控到位、版本一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ftmao.com/blog/blog/posts/rocketmq-fundamentals/&#34;&gt;RocketMQ 基础科普：推/拉/通知模式、异常处理与高并发实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;《RocketMQ 实战与核心原理》&lt;/li&gt;
&lt;li&gt;《RocketMQ 技术内幕》&lt;/li&gt;
&lt;li&gt;《Kafka 权威指南》&lt;/li&gt;
&lt;li&gt;《RabbitMQ 实战指南》&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;如果对你有帮助，欢迎在评论区交流你在 MQ 选型或异常处理上的经验。&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
