基于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中的消息,完成下单