Redis 作为消息队列的三种使用方式与 Spring Boot 实践
2026/5/10 15:24:46 网站建设 项目流程

目录

  1. Redis 为什么能够作为消息队列
  2. 三种消息队列实现方式概览
  3. Redis List 队列机制及 Spring 实战
  4. Redis Pub/Sub 发布订阅机制及使用方式
  5. Redis Stream:最强队列机制(含 ACK、消费组)
  6. Spring Boot 整合 Stream(完整可运行)
  7. Redis Stream 与 Kafka 的特点对比
  8. 使用场景总结

1. Redis 为什么可以用作消息队列

Redis 是一个基于内存的高性能 Key-Value 数据库,它的数据结构丰富且操作均为 O(1)。
队列的本质是“先进先出,按顺序取出”,而 Redis 的 List、Pub/Sub 与 Stream 结构分别可以满足不同层次的队列需求:

  • List:可以充当普通队列
  • Pub/Sub:提供实时的发布订阅
  • Stream:提供带持久化、消费组、ACK 确认机制的专业队列能力

这让 Redis 在轻量级 MQ 场景下非常灵活,也非常高效。


2. Redis 三种消息队列方案对比

方案持久化是否丢消息是否支持消费组是否需要 ACK使用难度适用场景
List(LPUSH/RPOP)支持有可能丢失不支持不支持最简单简单后台任务、异步执行
Pub/Sub不支持订阅者离线即丢失不支持不支持中等实时消息推送、广播通知
Stream支持不容易丢失支持支持相对复杂订单处理、任务调度、分布式队列

从功能完善度来看,Stream 是最推荐的方案。
从使用简单度来看,List 是最容易上手的。


3. Redis List 队列机制(LPUSH + RPOP)

List 是 Redis 最经典的队列实现方式。通过“左进右出”就可以模拟一个典型的 FIFO 队列。

特点说明

  1. 实现简单,可快速上手
  2. 使用 RedisTemplate 就能轻松实现
  3. 不支持消费者确认机制,消息投递后无法保证成功处理
  4. 多消费者会导致竞争同一条消息,不适合任务分布式分发

因此,List 更适合简易异步任务、低可靠场景。

生产者示例:

@AutowiredprivateStringRedisTemplateredisTemplate;publicvoidsendMessage(Stringmsg){redisTemplate.opsForList().leftPush("task_queue",msg);}

消费者示例:

@Scheduled(fixedDelay=1000)publicvoidconsumer(){Stringmsg=redisTemplate.opsForList().rightPop("task_queue");if(msg!=null){System.out.println("处理任务:"+msg);}}

这种方式虽然简单,但不具备强队列能力。


4. Redis Pub/Sub 发布订阅模式

Pub/Sub 提供了一种非常实时化的消息推送方式,它不存储历史消息,只有在线订阅者才能收到。

模式特点

  1. 适合实时通知,如系统消息、广播消息、在线聊天
  2. 不会保存消息,订阅者掉线即丢失
  3. 没有 ACK,无法保证每条消息被处理

Pub/Sub 不适合作为任务队列,但适合“实时推送”。

监听器配置

@ConfigurationpublicclassRedisConfig{@BeanMessageListenerAdapterlistenerAdapter(MessageReceiverreceiver){returnnewMessageListenerAdapter(receiver,"onMessage");}@BeanRedisMessageListenerContainercontainer(RedisConnectionFactoryfactory,MessageListenerAdapterlistenerAdapter){RedisMessageListenerContainercontainer=newRedisMessageListenerContainer();container.setConnectionFactory(factory);container.addMessageListener(listenerAdapter,newPatternTopic("notice"));returncontainer;}}

消费者

@ComponentpublicclassMessageReceiver{publicvoidonMessage(Stringmessage){System.out.println("收到通知:"+message);}}

生产者

redisTemplate.convertAndSend("notice","系统通知:服务器即将维护");

5. Redis Stream:专业级消息队列方案

Stream 是 Redis 5.0 引入的全新数据结构,是一套完整的消息队列系统,特点如下:

  1. 支持持久化,数据不会因断电丢失
  2. 支持消费者组,可由多个消费者组成消费集群
  3. 支持 ACK 确认机制,确保消息不会丢失
  4. 单条消息被确定处理后自动从 Pending 列表中移除
  5. 支持自动或手动 Claim,保证消息不会被遗忘
  6. 顺序性和性能都非常优秀

Stream 可以被认为是小型版的 Kafka,但更轻量、更容易部署。


6. Spring Boot 整合 Redis Stream

1)依赖引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

2)初始化消息队列的消费组

为了防止不存在的消费组导致报错,一般在项目启动时创建消费组:

@ComponentpublicclassStreamInit{@AutowiredprivateStringRedisTemplateredisTemplate;@PostConstructpublicvoidinit(){try{redisTemplate.opsForStream().createGroup("order_stream","order_group");}catch(Exceptionignored){}}}

3)生产者发送消息

@AutowiredprivateStringRedisTemplateredisTemplate;publicvoidsendOrder(StringorderNo){Map<String,String>map=newHashMap<>();map.put("orderNo",orderNo);redisTemplate.opsForStream().add("order_stream",map);}

4)消费者处理消息(包含 ACK)

@ComponentpublicclassOrderConsumerimplementsStreamListener<String,MapRecord<String,String,String>>{@AutowiredprivateStringRedisTemplateredisTemplate;@OverridepublicvoidonMessage(MapRecord<String,String,String>record){StringorderNo=record.getValue().get("orderNo");System.out.println("正在处理订单:"+orderNo);redisTemplate.opsForStream().acknowledge("order_stream","order_group",record.getId());}}

5)注册 Stream 监听器

@ConfigurationpublicclassStreamConfig{@BeanpublicRedisMessageListenerContainerlistenerContainer(RedisConnectionFactoryfactory,OrderConsumerconsumer){RedisMessageListenerContainercontainer=newRedisMessageListenerContainer();container.setConnectionFactory(factory);StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String,MapRecord<String,String,String>>options=StreamMessageListenerContainer.StreamMessageListenerContainerOptions.builder().pollTimeout(Duration.ofSeconds(2)).build();StreamMessageListenerContainer<String,MapRecord<String,String,String>>streamContainer=StreamMessageListenerContainer.create(factory,options);streamContainer.receiveAutoAck(Consumer.from("order_group","consumer_1"),StreamOffset.create("order_stream",ReadOffset.lastConsumed()),consumer);streamContainer.start();returncontainer;}}

至此,Redis Stream 的生产-消费整体链路完整实现,可以直接在实际项目中使用。


7. Redis Stream 与 Kafka 的对比分析

特点Redis StreamKafka
吞吐量中等偏高极高
消费机制消费组 + ACK消费组 + Offset
持久化方式内存主导 + AOF磁盘顺序写
依赖环境极简,部署容易较复杂,需要 Zookeeper 或 Kraft
使用场景中小型业务,订单流、异步任务海量日志、实时流处理、大型数据系统

结论:当系统规模较小时,Redis Stream 是简单高效的队列方案;当系统达到大规模吞吐需求时,Kafka 才是更合适的选择。


8. 使用场景总结

以下场景适合完全使用 Redis Stream 或 List/PubSub:

  • 订单创建后的异步处理
  • 秒杀请求异步落库
  • 延迟任务队列
  • 短信/邮件异步发送
  • 系统通知、用户消息推送
  • 日志或审计消息收集
  • 数据同步、事件驱动架构

Redis 的灵活性使它能够同时承担缓存、分布式锁和消息队列等多种角色,适用于多种中小型分布式系统架构。


结语

Redis 不仅是一个高性能的缓存数据库,同时也是一个非常灵活且强大的轻量级消息队列解决方案。依托于其多样化的数据结构、极高的读写性能以及简单易部署的特点,Redis 在现代微服务架构中扮演着远超“缓存”本身的角色。在许多中小型项目中,它可以承担消息传递、事件驱动、异步任务处理等职责,甚至可以在一定程度上替代专业消息中间件。

在 Spring 体系中,Redis 的集成方式非常成熟且丰富,无论是基于 List 的简易队列、基于 Pub/Sub 的实时广播消息,还是基于 Stream 的分布式消息队列,都可以通过 Spring Data Redis 顺畅地接入应用系统。其中 Redis Stream 是目前最值得推荐的方案,它具备消息持久化、消费者组、消息确认机制(ACK)、Pending 列表管理、顺序性保证等能力,能够提供接近 Kafka 那样的消息投递可靠性,同时又保持了 Redis 一贯的简单部署和轻量成本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询