业务场景选 Redis 队列还是 RabbitMQ 有什么区别?

文章导读
选 Redis 还是 RabbitMQ 做队列,核心取决于业务对消息可靠性的要求以及延迟敏感度。简单高频、允许少量丢失的场景用 Redis,复杂路由、要求消息不丢失的场景用 RabbitMQ。
📋 目录
  1. 核心选型标准
  2. Redis 队列落地实操
  3. RabbitMQ 可靠性配置
  4. 验证与监控方案
  5. 常见工程坑点
A A

选 Redis 还是 RabbitMQ 做队列,核心取决于业务对消息可靠性的要求以及延迟敏感度。简单高频、允许少量丢失的场景用 Redis,复杂路由、要求消息不丢失的场景用 RabbitMQ。

核心结论:业务对消息丢失零容忍选 RabbitMQ,追求极致吞吐且能接受少量丢失选 Redis。

  • 适用场景:Redis 用于缓存结合队列、秒杀计数;RabbitMQ 用于订单异步、系统解耦。
  • 关键指标:消息确认机制、持久化能力、延迟要求。
  • 风险提示:Redis 需防范消息丢失风险、RabbitMQ 需评估运维复杂度。

核心选型标准

选型需结合业务容忍度与运维成本,主要参考以下维度:

  1. 消息可靠性:如果丢一条消息会导致资损或客诉,必须上 RabbitMQ 并开启持久化与 ACK;如果是日志或非核心状态同步,Redis 够用。
  2. 延迟敏感度:根据社区基准测试参考,Redis 简单入队 QPS 可达 10 万 +,延迟通常在微秒级;RabbitMQ 在持久化模式下约为 2 万 -5 万 QPS,涉及网络协议和持久化,延迟在毫秒级。
  3. 运维成本:RabbitMQ 需要维护集群、镜像队列或_quorum_队列,运维成本高于 Redis 单实例或哨兵模式。

Redis 队列落地实操

Redis 实现队列主要有 List 和 Stream 两种结构,可靠性差异巨大。

业务场景选 Redis 队列还是 RabbitMQ 有什么区别?

1. List 结构(不推荐核心业务)

使用 LPUSHBRPOP 实现简单队列,但消费者宕机时消息会丢失。

# 生产者
LPUSH my_queue "{\"id\":1,\"data\":\"test\"}"

# 消费者
BRPOP my_queue 0

风险:消息弹出后若消费者崩溃,无机制找回消息。

2. Stream 结构(推荐)

使用 Consumer Group 机制,支持消息确认(ACK),类似 Kafka。

业务场景选 Redis 队列还是 RabbitMQ 有什么区别?
# 创建消费组
XGROUP CREATE my_stream my_group $ MKSTREAM

# 消费者读取消息
XREADGROUP GROUP my_group consumer1 COUNT 1 BLOCK 5000 STREAMS my_stream >

# 业务处理成功后确认
XACK my_stream my_group 1583476734000-0

注意:必须执行 XACK,否则消息会留在 PEL 列表中,导致重复消费或内存泄漏。

RabbitMQ 可靠性配置

RabbitMQ 需正确配置持久化和确认机制才能保证消息不丢失。

1. 队列与消息持久化

在声明队列时设置 durable=true,发送消息时设置 deliveryMode=2

业务场景选 Redis 队列还是 RabbitMQ 有什么区别?
# Spring Boot application.yml 配置示例
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual # 必须手动 ACK
        prefetch: 1 # 防止消费者过载

2. 手动 ACK 代码示例

在消费逻辑成功后手动提交确认,失败则拒绝并重新入队或进入死信队列。

@RabbitListener(queues = "order_queue")
public void handleOrder(Message message, Channel channel) {
    try {
        // 业务逻辑处理
        processOrder(message);
        // 手动 ACK
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
        // 拒绝消息,重新入队或丢弃
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
    }
}

验证与监控方案

上线后需通过具体命令和指标验证选型是否合适。

1. 消息堆积监控

  • Redis:使用 XLEN my_stream 查看 Stream 长度,或 LLEN my_queue 查看 List 长度。
  • RabbitMQ:使用命令 rabbitmqctl list_queues name messages_ready messages_unacknowledged 查看就绪和未确认消息数。

2. 消费延迟验证

  • 方法:记录消息产生时间与消费时间的差值。
  • 工具:RabbitMQ Management 插件可查看 Consumer Utilization 和 Message Rates;Redis 可结合 SLOWLOG 排查阻塞。

3. 异常日志检查

重点检查是否有消息确认失败、连接断开、NACK 次数激增等异常日志。

常见工程坑点

  • Redis 消息丢失:使用 List 做队列时,如果消费者宕机,弹出的消息可能丢失,核心业务务必使用 Stream 配合 XACK
  • RabbitMQ 性能误区:开启持久化和 ACK 会显著降低吞吐,非核心场景不要过度配置,可尝试关闭持久化测试性能瓶颈。
  • 运维复杂度:RabbitMQ 集群脑裂或元数据损坏可能导致服务不可用,需定期备份元数据,建议使用 Quorum Queues 替代镜像队列。
  • 混合使用陷阱:不要试图在一个系统中随意混用两者处理同一类消息,会导致协议不兼容和维护困难。
  • Redis 内存 eviction:确保 Redis 配置了合适的最大内存策略,避免队列消息因内存满被意外淘汰。