消息队列 RabbitMQ 入门

发布于:2026-05-11 #消息队列#RabbitMQ#后端 共 1,242 字 约 4 分钟

消息队列是微服务架构中解耦、异步、削峰的核心中间件。本篇聚焦 RabbitMQ 的架构与最佳实践。

为什么需要消息队列

解耦、异步、削峰是三大核心场景。

解耦

订单系统无需直接调用库存、积分、短信等服务,只需将订单事件写入 MQ,下游服务异步消费。

Text
UTF-8|3 Lines|
订单系统 -> MQ -> 库存系统
               -> 积分系统
               -> 短信服务

异步 (性能提升)

Text
UTF-8|2 Lines|
同步: 写库(50ms) + 发邮件(300ms) + 发短信(300ms) = 650ms
异步: 写库 + 发消息到 MQ = 55ms (下游异步消费)

削峰

高并发时将请求先写入 MQ,消费者按自身能力拉取处理,保护数据库不被冲垮。

主流 MQ 对比

中间件特点适用场景
RabbitMQ稳定可靠,路由丰富,Erlang 实现业务消息、异步、延迟
RocketMQ高吞吐、高可用,Java电商、交易、金融
Kafka超高吞吐,适合流式数据日志采集、埋点、实时计算

RabbitMQ 核心模型

Text
UTF-8|1 Line|
Producer -> Exchange -> Queue -> Consumer
角色说明
Producer发送消息
Consumer消费消息
BrokerRabbitMQ 服务节点
Exchange交换机,根据路由规则投递
Queue队列,存储消息
BindingExchange 与 Queue 的绑定关系
Routing Key路由键,决定消息去向
Channel复用 TCP 的逻辑通道

Exchange 类型

direct — 精确匹配

Routing Key 完全一致才投递。适合按业务类型分发。

Text
UTF-8|1 Line|
绑定: order.created -> order.created.queue

fanout — 广播

无视 Routing Key,将消息发给所有绑定的队列。适合全局通知。

Text
UTF-8|1 Line|
商品修改事件 -> 商品搜索服务、索引服务、缓存服务

topic — 通配匹配

Text
UTF-8|4 Lines|
* 匹配一个单词
# 匹配零个或多个单词
order.*       -> order.created, order.cancelled
product.#     -> product.price.changed, product.stock.changed

消息确认机制

生产者确认 (Publisher Confirm)

确保消息成功到达 Broker,失败可重试或记录日志。

消费者确认 (Consumer Ack)

方式说明
自动确认投递即删除,可能丢消息
手动确认处理完业务逻辑后调用 ack

推荐手动确认:

Text
UTF-8|1 Line|
消费消息 -> 执行业务 -> 成功 ack / 失败 nack 或重回队列

可靠投递三阶段

阶段风险对策
发送阶段生产者发送失败Publisher Confirm、失败重试
存储阶段MQ 宕机丢数据队列 + 消息持久化
消费阶段消费者处理失败手动 ack、重试、死信队列

重复消费与幂等性

消息系统无法保证仅消费一次,消费者必须做幂等:

  • 业务唯一 ID 去重
  • 数据库唯一索引
  • Redis 布隆过滤器
  • 状态机校验
Text
UTF-8|4 Lines|
收到 payment.success 消息
  -> 查询订单状态
  -> 已支付:直接返回
  -> 未支付:更新状态 + 流水记录

死信队列 (DLQ)

处理无法被正常消费的消息,用于异常隔离和人工排查:

Text
UTF-8|1 Line|
消费失败 -> 重试耗尽 -> 死信队列 -> 人工介入

TTL 与延迟消息

通过死信交换器 + TTL 实现延迟消息:

Text
UTF-8|4 Lines|
发消息到延迟队列 (TTL=30min)
  -> TTL 到期
  -> 死信交换器转发到业务队列
  -> 消费者处理

适用于:订单超时关闭、优惠券到期提醒。

消息分发控制

Text
UTF-8|1 Line|
prefetch = 1   # 每次只给消费者一个未确认消息

保证消费者之间负载均衡,避免消息堆积在某个慢消费者。

常见注意事项

  • 持久化队列 + 持久化消息缺一不可
  • 异步系统中需考虑最终一致性
  • 幂等设计是必须的,不要依赖消息不重复
  • 死信队列 + 告警机制必须配套
  • MQ 不适用于强一致性场景