选 Redis 还是 RabbitMQ 做队列,核心取决于业务对消息可靠性的要求以及延迟敏感度。简单高频、允许少量丢失的场景用 Redis,复杂路由、要求消息不丢失的场景用 RabbitMQ。
核心结论:业务对消息丢失零容忍选 RabbitMQ,追求极致吞吐且能接受少量丢失选 Redis。
- 适用场景:Redis 用于缓存结合队列、秒杀计数;RabbitMQ 用于订单异步、系统解耦。
- 关键指标:消息确认机制、持久化能力、延迟要求。
- 风险提示:Redis 需防范消息丢失风险、RabbitMQ 需评估运维复杂度。
核心选型标准
选型需结合业务容忍度与运维成本,主要参考以下维度:
- 消息可靠性:如果丢一条消息会导致资损或客诉,必须上 RabbitMQ 并开启持久化与 ACK;如果是日志或非核心状态同步,Redis 够用。
- 延迟敏感度:根据社区基准测试参考,Redis 简单入队 QPS 可达 10 万 +,延迟通常在微秒级;RabbitMQ 在持久化模式下约为 2 万 -5 万 QPS,涉及网络协议和持久化,延迟在毫秒级。
- 运维成本:RabbitMQ 需要维护集群、镜像队列或_quorum_队列,运维成本高于 Redis 单实例或哨兵模式。
Redis 队列落地实操
Redis 实现队列主要有 List 和 Stream 两种结构,可靠性差异巨大。
1. List 结构(不推荐核心业务)
使用 LPUSH 和 BRPOP 实现简单队列,但消费者宕机时消息会丢失。
# 生产者
LPUSH my_queue "{\"id\":1,\"data\":\"test\"}"
# 消费者
BRPOP my_queue 0风险:消息弹出后若消费者崩溃,无机制找回消息。
2. Stream 结构(推荐)
使用 Consumer Group 机制,支持消息确认(ACK),类似 Kafka。
# 创建消费组
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。
# 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 配置了合适的最大内存策略,避免队列消息因内存满被意外淘汰。