基于Redis实现消息队列
使用Redis实现消息队列可以使用不同的数据结构,本文将分开详细叙述不同的方式
基于List模拟消息队列
使用LPUSH添加消息,使用BRPOP阻塞等待pop消息来实现消息队列
优点:
- 利用Redis存储,不受JVM内存限制
- 基于Redis的持久化机制,数据安全性有保证
- 可以满足消息有序性
缺点: - 无法避免消息丢失
- 只支持单消费者
基于PubSub的消息队列
PubSub是Redis2.0引入的消息传递模型,消费者可以订阅多个channel,生产者向对应channel发送消息后,所以订阅者都能收到消息
基本命令
- SUBSCRIBE channel xxx:订阅一个或多个频道
- PUBLISH channel msg:向一个频道发送消息
- PSUBSCRIBE pattern xxx:订阅与pattern格式匹配的所有频道
优点:
- 采用发布订阅模型,支持多生产,多消费
缺点: - 不支持数据持久化
- 无法避免消息丢失
- 消息堆积有上限,超出时数据丢失
基于Stream的消息队列
添加消息:
XADD key *(代表自动生成id) k v
读取消息:
XREAD 读几条消息 阻塞时间 key $(读取最新消息)
在业务中可以循环调用XREAD阻塞来查询最新消息,实现持续监听队列的效果
注意:当指定$时,代表读取最新的消息,如果处理一条消息的过程中,又来了两条消息,那下次处理的只能是最新的消息,发生消息遗漏的问题
特点:
- 消息可回溯
- 一个消息可以被多个消费者读取
- 可以阻塞读取
- 有消息漏读的风险
基于Stream的消息队列-消费者组模式
消费者组:将多个消费者划分到一个组中,监听同一个队列
创建消费者组:
XGROUP CREATE key groupName id
消费组读取消息
XREADGROUP GROUP group consumer key id
id可以指定 ‘>’ 从下一个未消费的消息开始
基于Stream实现秒杀业务
- 创建Stream消息队列
- 在认定有抢购资格后,直接向Stream中添加消息
- 项目启动时,开启一个县城任务,尝试获取stream中的消息,完成下单