spring cloud RabbitMQ

RabbitMQ | RocketMQ | Kafka 基础选型

一、三款 MQ 本质差异(先建立认知)

维度 RabbitMQ RocketMQ Kafka
出身 AMQP,Erlang 阿里,Java LinkedIn,Scala/Java
吞吐量 万级 ~ 数万 十万 ~ 百万 百万 ~ 千万
延迟 最低(ms 级) 很低 低(但批次攒数据)
消息模型 Exchange + Queue Topic + Tag + Queue Topic + Partition
顺序消息 ❌(难) ✅(单Queue) ✅(Partition)
延迟队列 TTL+DLX / 插件 ✅原生支持 ❌不支持
事务消息 ❌(新版有但弱)
死信队列 ❌(需自行实现)
消费模式 Push Push/Pull Pull
运维复杂度 简单 中等 较复杂
典型用途 业务解耦 / 延迟 / RPC-like 金融 / 订单 / 事务 日志 / 埋点 / 流计算

二、RabbitMQ(你正在学的 ✅)

✅ 适合

  • 业务系统解耦
    • 订单 → 库存 / 短信 / 积分
  • 延迟队列(30 分钟关单 ✅)
  • 请求少 / 实时性高
  • 中小型 / 中大型单体或微服务

❌ 不适合

  • 超高通量(日志、埋点)
  • 海量堆积(TB 级)
  • 流式计算

✅ 典型场景

复制代码
下单 → 库存扣减
下单 → 发送短信
订单创建 → 30分钟未支付关单(TTL+DLX)

👉 你现在的项目首选 RabbitMQ


三、RocketMQ(阿里系 / 金融级)

✅ 适合

  • 电商 / 金融 / 支付
  • 需要:
    • 顺序消息(同一订单顺序)
    • 事务消息(本地事务 + MQ 最终一致)
    • 延迟消息(18 个固定等级)
    • 海量堆积
  • Spring Cloud Alibaba 原生支持

❌ 不适合

  • 日志采集(不如 Kafka 经济)
  • 简单延迟队列(不如 RabbitMQ 灵活,只固定等级)

✅ 典型场景

复制代码
支付成功 → 账户扣款(事务消息)
订单流水 → 按顺序落库
秒杀 → 削峰

四、Kafka(大数据 / 日志 / 流计算)

✅ 适合

  • 日志收集(ELK)
  • 用户行为埋点
  • 指标采集
  • 实时流计算(Flink / Spark Streaming)
  • 超高吞吐 + 数据重放

❌ 不适合

  • 业务延迟队列
  • 死信处理
  • 单条消息 ACK 精细控制
  • 简单业务解耦(杀鸡用牛刀)

✅ 典型场景

复制代码
Nginx / 应用日志 → Kafka → Logstash → ES
用户点击流 → Kafka → Flink → 实时大盘

五、选型对比速记表(面试背这个 ✅)

你要不要...
业务解耦 + 延迟队列 + 简单运维 RabbitMQ
电商交易 + 事务消息 + 顺序消息 RocketMQ
日志 / 流数据 / 超高吞吐 Kafka

六、真实公司常见搭配(你以后会看到)

复制代码
RabbitMQ  → 核心业务(订单 / 支付 / 通知)
RocketMQ  → 交易核心 / 分布式事务(阿里系)
Kafka     → 日志 / 埋点 / 实时分析

不是三选一,经常三者共存


七、结合你当前阶段的建议 ✅

你现在是:

  • ✅ 学 Spring Cloud Alibaba
  • ✅ 做订单 / 支付 / 关单
  • ✅ 需要延迟队列 + DLQ + 易部署

👉 RabbitMQ 是你现在最合理选择

RocketMQ / Kafka 了解即可,先不急着深入,除非:

  • 公司已用 RocketMQ
  • 或准备做日志 / 大数据方向

八、一句话总结 ✅

RabbitMQ = 业务解耦 + 延迟队列(你当前必学)

RocketMQ = 电商交易 + 事务消息 + 顺序消息

Kafka = 日志 + 流计算 + 超高吞吐

中大型系统常三者并存,各司其职


一、RabbitMQ 整体架构与原理

RabbitMQ 是实现 AMQP 0-9-1 协议 的开源消息代理(Message Broker),核心思想是:生产者不直接发消息给队列,而是发给交换机,由交换机按规则路由到队列

核心组件

组件 说明
Broker RabbitMQ 服务节点,负责接收、存储、转发消息
Producer(Publisher) 消息生产者,发送消息到 Exchange
Consumer 消息消费者,从 Queue 拉取或被动接收推送消息
Exchange(交换机) 路由中枢,不存储消息,按类型+Binding规则决定消息去哪个Queue
Queue(队列) 真正存储消息的地方,支持持久化、TTL、长度限制
Binding(绑定) Exchange ↔ Queue 的关联关系,附带 Binding Key(路由匹配依据)
Routing Key 生产者发消息时携带的字符串,Exchange 用它做路由判断
Virtual Host(vhost) 逻辑隔离空间,各 vhost 有独立 Exchange/Queue/权限(类似 Namespace)
Connection 客户端与 Broker 间的 TCP 长连接
Channel(信道) Connection 内的虚拟通道,实际执行 declare/send/consume,多路复用减少 TCP 开销

消息完整流转流程

  1. Producer 与 Broker 建立 TCP Connection → 开启 Channel
  2. 声明 Exchange(如不存在)、Queue、Binding
  3. Producer 发送消息到 Exchange,指定 Routing Key 和消息属性(持久化、优先级、TTL等)
  4. Exchange 根据类型 + Binding 规则匹配,将消息拷贝路由到符合条件的 Queue(s)
  5. 消息在 Queue 中等待,Consumer 订阅 Queue
  6. Broker 推(Push)消息给 Consumer(Basic.Consume),或 Consumer 主动拉(Basic.Get,不推荐)
  7. Consumer 处理完发送 ACK,Broker 标记消息可删除;若 NACK/无 ACK 可按配置重入队或进死信队列

⚠️ 注意 :Exchange 本身不存消息,若无匹配 Queue 且未设置备用交换器(Alternate Exchange),消息会被丢弃


二、四种 Exchange 交换机详解

RabbitMQ 内置四种标准交换机类型,路由规则是核心区别。

1. Direct Exchange(直连交换机)------ 精确匹配

  • 路由规则 :消息 Routing Key 必须与 Binding Key 完全相同(大小写敏感),才路由到对应 Queue

  • 特点:简单高效,支持一个 Key 绑定多个 Queue(实现单播+伪多播)

  • 典型场景

    • 日志分级:error → 告警队列,info → 归档队列
    • 订单状态分发:order.created → 库存队列,order.paid → 结算队列
  • 默认交换机 :RabbitMQ 自带一个匿名 "" Exchange(type=direct),自动用 Queue 名作 Binding Key,所以不显式声明交换机也能发消息

    Queue A ← bind "order.create"
    Queue B ← bind "order.pay"

    msg(routingKey="order.create") → 只到 Queue A
    msg(routingKey="order.pay") → 只到 Queue B


2. Fanout Exchange(扇形/广播交换机)------ 广播

  • 路由规则忽略 Routing Key ,将消息复制并广播到所有绑定到此 Exchange 的 Queue
  • 特点:性能最好(无匹配计算),彻底解耦发布者与订阅者拓扑
  • 典型场景
    • 系统公告 / 运维广播

    • 订单创建后 → 同时通知库存、物流、营销、发邮件等多个系统

    • 分布式缓存失效通知

      Queue A、B、C 都 bind 到 fanout_exchange
      发任意消息 → A、B、C 各收到一份拷贝


3. Topic Exchange(主题交换机)------ 通配符匹配 ⭐最灵活

  • 路由规则 :Routing Key 用 . 分隔单词(如 order.created.vip),Binding Key 支持通配符:
    • * ------ 匹配恰好一个单词
    • # ------ 匹配零个或多个单词
  • 特点:兼具精确与模糊匹配,适合多维度分类订阅
  • 典型场景
    • 日志系统:log.error.# 接收所有错误日志,*.usa.* 接收美国区域消息

    • 微服务事件总线:user.* 订阅用户相关所有事件,order.*.paid 订阅各类订单支付

      Binding: Queue A ← "order.*.vip"
      Binding: Queue B ← "order.#"

      routingKey="order.created.vip" → A✓ B✓
      routingKey="order.paid.vip" → A✓ B✓
      routingKey="order.created.normal" → A✗ B✓
      routingKey="order.paid" → A✗ B✓(#匹配0词)


4. Headers Exchange(头交换机)------ 基于消息头属性匹配

  • 路由规则忽略 Routing Key ,根据消息 headers(Map<String,Object>)匹配
    • 绑定时设 x-match 参数:
      • x-match = all → 所有 header 键值对均匹配
      • x-match = any → 任意一个匹配即可
  • 特点 :支持多条件复杂筛选,但性能低于其他三种,使用较少(Topic 常可替代)
  • 典型场景 :需多属性组合路由,如 type=order AND priority=high
java 复制代码
// 绑定时
Map<String,Object> headers = new HashMap<>();
headers.put("type", "order");
headers.put("priority", "high");
headers.put("x-match", "all");
channel.queueBind(queueName, headersExchange, "", headers);

// 发送时
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .headers(new HashMap<String,Object>() {{
        put("type", "order");
        put("priority", "high");
    }}).build();
channel.basicPublish("headers.ex", "", props, body);

四种交换机对比速查

类型 路由依据 匹配方式 性能 使用频率 典型场景
Direct Routing Key 完全相等 ★★★★ ★★★★★ 点对点、日志分级
Fanout 无(忽略Key) 广播全部 ★★★★ ★★★★ 广播通知、多系统联动
Topic Routing Key */#通配符 ★★★ ★★★★★ 分类订阅、事件总线
Headers Headers属性 K-V全/任匹配 ★★ ★★ 多条件复杂路由(少用)

三、其他重要概念详解

Queue 属性

  • Durable(持久化) :设为 true 时 Queue 元数据存磁盘,Broker 重启后保留(消息本身还需设 deliveryMode=2 才持久化)
  • Exclusive(排他):仅允许当前 Connection 使用,连接关闭自动删除
  • Auto-delete:最后一个 Consumer 取消订阅后自动删除
  • 支持设置 x-message-ttl (消息过期时间)、x-max-length (队列最大长度)、x-dead-letter-exchange(死信交换机)

消息确认机制(ACK)

  • autoAck=true:Broker 发出即删,可能丢消息
  • autoAck=false:Consumer 手动 basic.ack,处理完才删;异常可 basic.nack(requeue) 重入队或丢弃 → 推荐生产环境使用

死信队列(DLQ --- Dead Letter Queue)

以下情况消息变"死信":

  • 被 Consumer 拒绝/Nack 且不重入队
  • 消息 TTL 过期
  • 队列超出长度限制

死信交换机(DLX --- Dead Letter Exchange)

通过在 Queue 声明时设置 x-dead-letter-exchangex-dead-letter-routing-key,死信会被转发到指定 DLX→DLQ,常用于延迟队列(结合 TTL( Time To Live)+DLX)异常消息兜底处理

Virtual Host(vhost)

  • 同一 Broker 内逻辑隔离,不同 vhost Exchange/Queue 互不可见
  • 常用于:多环境隔离(/dev/test/prod)、多租户隔离
bash 复制代码
rabbitmqctl add_vhost /prod
rabbitmqctl set_permissions -p /prod user ".*" ".*" ".*"

Connection & Channel

  • Connection:TCP 连接,建立开销大
  • Channel:轻量级虚拟通道,复用 Connection,每个线程建议用独立 Channel,避免并发问题
  • 几乎所有 AMQP 操作(exchangeDeclare、queueDeclare、basicPublish、basicConsume)都在 Channel 上进行

Docker 部署 RabbitMQ 的「生产可用标准方案」


一、最快方式(测试 / 本地开发 ✅)

1️⃣ 一行命令启动(带 Web 管理界面)

bash 复制代码
docker run -d \
  --name rabbitmq \
  -p 5672:5672 \
  -p 15672:15672 \
  rabbitmq:3.12-management

访问地址

类型 地址
AMQP(程序用) localhost:5672
Web 管理台 http://localhost:15672

默认账号

复制代码
用户名:guest
密码:guest

⚠️ guest 用户只能 localhost 访问


二、推荐方式(生产环境 ✅✅)

1️⃣ 创建目录(数据持久化)

bash 复制代码
mkdir -p /opt/rabbitmq/{data,logs}

2️⃣ docker-compose.yml(强烈推荐)

yaml 复制代码
version: '3.8'

services:
  rabbitmq:
    image: rabbitmq:3.12-management
    container_name: rabbitmq
    restart: always
    hostname: rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: Admin123!
      RABBITMQ_DEFAULT_VHOST: /
    ports:
      - "5672:5672"    # AMQP
      - "15672:15672"  # Web UI
    volumes:
      - /opt/rabbitmq/data:/var/lib/rabbitmq
      - /opt/rabbitmq/logs:/var/log/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "ping"]
      interval: 30s
      timeout: 10s
      retries: 5

启动:

bash 复制代码
docker compose up -d

3️⃣ 登录 Web 控制台

复制代码
http://服务器IP:15672

用户名:admin
密码:Admin123!

三、创建 vhost / 用户(生产必做 ✅)

进入容器:

bash 复制代码
docker exec -it rabbitmq bash

创建 vhost

bash 复制代码
rabbitmqctl add_vhost /prod

创建用户

bash 复制代码
rabbitmqctl add_user app_user App@123

授权

bash 复制代码
rabbitmqctl set_permissions -p /prod app_user ".*" ".*" ".*"

四、Spring Boot 对应配置 ✅

yaml 复制代码
spring:
  rabbitmq:
    host: 服务器IP
    port: 5672
    username: app_user
    password: App@123
    virtual-host: /prod

五、确认 RabbitMQ 是否 OK ✅

bash 复制代码
docker ps
docker logs rabbitmq

Web 页面能看到:

  • Queues
  • Exchanges
  • Connections

✅ 说明部署成功


六、生产环境必须注意的 5 件事 ⚠️

项目 建议
数据目录 必须 volume 挂载
默认 guest 禁用或限制
端口暴露 外网只开 5672
Web 管理台 内网访问 / VPN
内存 至少 2G

七、你这套 Spring Cloud 延迟队列能用吗?

完全可以用

✅ TTL + DLX + 死信队列 不需要额外插件

✅ Docker 版本 ≥ 3.8 都没问题


八、一句话总结 ✅

Docker 部署 RabbitMQ 用 3.x-management 镜像 + docker-compose + 数据卷 + 自定义用户,就是生产级方案。


rabbit 使用springcloud 创建队列 生成消息 交给交换机 进入不同得队列 之后消费普通队列消息 和消费死信队列消息代码

下面覆盖你关心的 全部点

✅ Spring Cloud / Spring Boot

✅ 创建 延迟队列(TTL)

✅ 创建 死信队列(DLQ)

✅ 创建 普通业务队列

✅ 交换机 → 不同队列

✅ 生产消息

✅ 消费 普通队列

✅ 消费 死信队列(关单)


一、依赖(pom.xml)

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

二、application.yml

yaml 复制代码
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

三、RabbitMQ 配置类(核心 ✅)

只在这一处声明所有 Queue / Exchange / Binding

java 复制代码
@Configuration
public class RabbitConfig {

    // ================= 交换机 =================
    public static final String ORDER_EXCHANGE = "order.exchange";

    // ================= 普通队列(支付成功) =================
    public static final String ORDER_PAY_QUEUE = "order.pay.queue";
    public static final String ORDER_PAY_KEY = "order.pay";

    // ================= 延迟队列(30分钟) =================
    public static final String ORDER_DELAY_QUEUE = "order.delay.queue";
    public static final String ORDER_DELAY_KEY = "order.delay";

    // ================= 死信队列(关单) =================
    public static final String ORDER_CLOSE_QUEUE = "order.close.queue";
    public static final String ORDER_CLOSE_KEY = "order.close";

    // ================= 死信交换机 =================
    public static final String ORDER_DLX = "order.dlx";

    /* ========== 交换机 ========== */
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange(ORDER_EXCHANGE, true, false);
    }

    @Bean
    public DirectExchange orderDlx() {
        return new DirectExchange(ORDER_DLX, true, false);
    }

    /* ========== 普通队列(支付成功) ========== */
    @Bean
    public Queue orderPayQueue() {
        return new Queue(ORDER_PAY_QUEUE, true);
    }

    @Bean
    public Binding orderPayBinding() {
        return BindingBuilder.bind(orderPayQueue())
                .to(orderExchange())
                .with(ORDER_PAY_KEY);
    }

    /* ========== 死信队列(关单) ========== */
    @Bean
    public Queue orderCloseQueue() {
        return new Queue(ORDER_CLOSE_QUEUE, true);
    }

    @Bean
    public Binding orderCloseBinding() {
        return BindingBuilder.bind(orderCloseQueue())
                .to(orderDlx())
                .with(ORDER_CLOSE_KEY);
    }

    /* ========== 延迟队列(重点⭐) ========== */
    @Bean
    public Queue orderDelayQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-message-ttl", 30 * 60 * 1000);      // 30分钟
        args.put("x-dead-letter-exchange", ORDER_DLX);
        args.put("x-dead-letter-routing-key", ORDER_CLOSE_KEY);
        return new Queue(ORDER_DELAY_QUEUE, true, false, false, args);
    }

    @Bean
    public Binding orderDelayBinding() {
        return BindingBuilder.bind(orderDelayQueue())
                .to(orderExchange())
                .with(ORDER_DELAY_KEY);
    }
}

四、发送消息(生产者)

1️⃣ 下单 → 进延迟队列

java 复制代码
@Component
@RequiredArgsConstructor
public class OrderProducer {

    private final RabbitTemplate rabbitTemplate;

    public void createOrder(Long orderId) {
        String msg = "orderId=" + orderId;
        rabbitTemplate.convertAndSend(
                RabbitConfig.ORDER_EXCHANGE,
                RabbitConfig.ORDER_DELAY_KEY,
                msg
        );
    }
}

2️⃣ 支付成功 → 进普通队列

java 复制代码
public void paySuccess(Long orderId) {
    String msg = "orderId=" + orderId;
    rabbitTemplate.convertAndSend(
            RabbitConfig.ORDER_EXCHANGE,
            RabbitConfig.ORDER_PAY_KEY,
            msg
    );
}

支付成功只改数据库,不删 MQ 消息


五、消费普通队列(支付成功)

java 复制代码
@Component
@Slf4j
@RabbitListener(queues = RabbitConfig.ORDER_CLOSE_QUEUE)
public void closeOrder(String msg, Channel channel,
                       @Header(AmqpHeaders.DELIVERY_TAG) long tag) {

    try {
        // 1. 业务处理
        handleOrder(msg);

        // 2. 成功 → ACK
        channel.basicAck(tag, false);

    } catch (Exception e) {
        log.error("关单失败", e);

        // 3. 失败 → NACK(不重入队,进 DLQ)
        try {
            channel.basicNack(tag, false, false);
        } catch (IOException ex) {
            log.error("NACK 失败", ex);
        }
    }
}

六、消费死信队列(30分钟未支付 → 关单 ✅)

java 复制代码
@Component
@Slf4j
public class OrderCloseConsumer {

    @RabbitListener(queues = RabbitConfig.ORDER_CLOSE_QUEUE)
    public void closeOrder(String msg, Channel channel,
                           @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {

        Long orderId = extractOrderId(msg);

        // ✅ 查数据库
        Order order = orderMapper.selectById(orderId);

        if (order != null && order.getStatus() == UNPAID) {
            orderMapper.updateStatus(orderId, CLOSED);
            log.info("订单超时关闭:{}", orderId);
        }

        channel.basicAck(tag, false);
    }
}

这是标准答案

✅ 不删 MQ

✅ 用 DB 状态兜底


七、完整消息流向(你这套代码的效果)

复制代码
下单
 ↓
order.delay.queue(TTL=30min,❌无消费者)
 ↓ 30分钟
order.dlx
 ↓
order.close.queue(✅消费)
 ↓
DB 未支付 → 关闭订单

支付成功
 ↓
order.pay.queue(✅消费)
 ↓
支付业务处理

八、一句话总结(你可以放心用)

延迟队列不消费

死信队列才消费

支付成功只改 DB

30 分钟到 DLQ 再关单


MQ消息堆积处理方案


一、什么叫 RabbitMQ 消息堆积?

生产者发消息速度 > 消费者处理速度 → Queue 中 Ready 消息持续增长

Web 管理台看到:

  • Ready 很大
  • Unacked 不大
  • Consumers 在线但处理不过来

二、先确认是哪种原因(很重要)

✅ 常见原因

原因 表现
消费者太慢(IO / DB / 外部接口) Ready↑,CPU 不高
消费者数量太少 Ready↑
消费者挂了 / ACK 没回 Ready 不变 / Unacked↑
突发流量(秒杀 / 批量导入) 短时间堆积
消息体太大 内存 / 磁盘压力大
消费者异常一直重试 Unacked↑ / 阻塞

👉 先查 RabbitMQ Management → Queues → Graph


三、消息堆积的处理方案(按优先级)


✅ 方案 1:增加消费者(最常用 ✅)

① 多启几个消费者实例(横向扩容)

yaml 复制代码
spring:
  rabbitmq:
    listener:
      simple:
        concurrency: 2
        max-concurrency: 8

或干脆:

  • 起 2~4 个 Pod / 进程
  • 同 Queue 多 Consumer 竞争消费

✅ RabbitMQ 自动 Round-Robin


✅ 方案 2:提高 prefetch(批量拉取)

默认 prefetch=1(太保守)

yaml 复制代码
spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 50   # 或 100

⚠️ 注意:

  • 不要太大(内存 / Unacked)
  • 配合 ACK 使用

"我(消费者)一次向 MQ 申请拿 50 条消息(Prefetch=50),我拿着这 50 条去慢慢处理,处理完一条我就手动喊一声 ACK 告诉 MQ 可以删了。"


✅ 方案 3:优化消费者处理逻辑(治本)

  • 减少 DB 操作(批量写)
  • 异步 / 并行
  • 去掉同步 HTTP 调用
  • 不必要逻辑移出 MQ 消费线程

❌ 典型反例:

java 复制代码
for (Order o : list) {
    restTemplate.postForObject(...); // ❌ 慢
}

✅ 方案 4:队列拆分(业务隔离)

原来:

复制代码
order.queue ← 创建 + 支付 + 取消 + 关单

拆成:

复制代码
order.create.queue
order.pay.queue
order.close.queue

✅ 互不影响

✅ 可单独扩容


✅ 方案 5:限流 / 削峰(生产者侧)

  • 前端限流
  • 网关限流
  • 批量任务错峰(夜间跑)
  • 使用 延迟队列分散峰值

✅ 方案 6:已有大量堆积时"追上来"

临时措施 ✅

  1. 临时扩容消费者(2~5倍)
  2. 提高 prefetch
  3. 暂时简化消费逻辑(只落库 / 只标记)
  4. 追平后再恢复正常

⚠️ 不要:

  • 删队列
  • 清消息(除非可丢失)

✅ 方案 7:设置队列上限 / TTL(防雪崩)

java 复制代码
x-max-length = 100000
x-overflow = drop-head / reject-publish

✅ 防止 MQ 把磁盘 / 内存拖垮


四、如果消费者挂了导致堆积

现象 处理
Ready↑,Unacked=0 重启消费者
Unacked↑ 检查 ACK / NACK 逻辑
一直 NACK(requeue=true) 改为有限重试 + DLQ

五、延迟队列场景(你之前那个)要特别注意 ⚠️

❌ 延迟队列(TTL 队列)堆积是正常的

  • 消息在等 TTL 到期
  • 不算异常

✅ 只有 关单队列(DLQ)堆积 需要处理


六、防堆积的最佳实践(生产总结)

✅ 多 Consumer + prefetch

✅ 消费逻辑轻

✅ 业务拆分队列

✅ 关单靠 DB 状态,不重消费

✅ 监控:Ready > 阈值 → 告警

✅ 限流 + 错峰


七、一句话总结 ✅

RabbitMQ 消息堆积先查原因 → 优先加消费者 / 提高 prefetch / 优化消费逻辑 → 必要时队列拆分 / 限流 → 已有堆积临时扩容追平,不删消息


① RabbitMQ 整体流程

Producer → Exchange → RoutingKey/Binding → Queue → Consumer → ACK

② 四种交换机区别 + 使用场景

Direct / Fanout / Topic / Headers(尤其 Topic 通配符)

③ 延迟队列怎么做 & 为什么延迟队列不消费

TTL + DLX,支付成功只改 DB,关单时查状态

④ 消息不丢失怎么保证

Exchange durable + Queue durable + Message PERSISTENT + manual ACK + DLX

⑤ 消息重复 / 幂等怎么处理

订单号唯一约束 / 状态判断 / 乐观锁

⑥ 消息堆积怎么处理

加消费者 / prefetch / 队列拆分 / 限流

相关推荐
Devin~Y1 小时前
从Spring Boot到AI Agent:大厂Java微服务面试三轮实战问答解析
java·spring boot·redis·spring cloud·微服务·ai·kafka
装不满的克莱因瓶1 小时前
Spring 全家桶与 Spring 6 新特性详解:从 IoC 到云原生时代
java·spring·云原生·jdk·新特性·spring6
装不满的克莱因瓶1 小时前
JSON 处理与内嵌 Tomcat 部署:Spring Boot 如何实现前后端数据交互与一键启动?
java·spring boot·spring·架构·tomcat·json
J2虾虾2 小时前
Spring Boot实现发邮件功能
java·spring boot·spring
jeffer_liu2 小时前
Spring AI 生产级实战-结构化输出
java·人工智能·后端·spring·大模型
程序猿乐锅2 小时前
【苍穹外卖|Day01】项目初识:从多模块结构到 OpenAPI 接口文档踩坑
java·spring·maven·mybatis
jasnet_u2 小时前
SpringCloud中服务集成PlumeLog日志系统
spring·spring cloud·plumelog·日志收集
Tenifs2 小时前
深入对比分析 RabbitMQ、RocketMQ 和 Kafka
后端·kafka·消息队列·rabbitmq·rocketmq·爱编程的阿彬
linweidong2 小时前
Java 后端开发面试 50 个高频易混淆知识点详解
java·spring boot·spring·spring cloud·面试·mybatis·spring事务