「黑马点评」七、Redis 消息队列介绍
消息队列入门
消息队列:确保消息至少被消费一次,也意味着持久化

image.png|500
主流的消息队列:Kafka、RabbitMQ、rocketMQ
Redis 提供的消息队列
- List:基于 List 结构模拟消息队列
- PubSub:基本的点对点消息模型
- Stream:比较完善的消息队列模型
基于 List 结构模拟消息队列
Redis 的 List 结构是双向链表,利用 LPUSH、RPOP 或 RPUSH、LPOP 实现队列,但是这样是非阻塞式的,会立即返回 null,如果想要 JVM 阻塞队列那样的阻塞式获取需要使用 BRPOP 或 BLPOP 实现阻塞效果

image.png|500
优点:
- 利用 Redis 存储,不受 JVM 内存上限
- 基于 Redis 持久化机制,安全性高一些
- 满足消息有序性
缺点:
- 无法避免消息丢失(宕机)
- 只支持单消费者
基于 PubSub 的消息队列
Publish & Subscribe,消费者可以订阅一个或多个 channel,生产者可以向对应 channel 发送消息,所有订阅者都可以接受到消息

image.png|500
优点:
- 发布订阅模型,可以实现多生产、多订阅
缺点:
- 不支持数据持久化
- 无法避免消息丢失(发完没人收就没了)
- 消息堆积有上限,超出则丢失
基于 Stream 的消息队列
Redis 5.0 新引入的数据结构,可以实现功能非常完善的消息队列
发送消息:XAAD xadd order * k1 v1

image.png|500
读取消息:XREAD xread count 1 block 2000 streams order 0
0 代表第一个消息

image.png|500
使用阻塞的方式读取最新消息: xread count 1 block 0 streams order $
$ 代表(启动读取后的)最新的一条消息,也就是最右端,可能会出现漏读的情况,所以使用 ID 更好

image.png|500
优点:
- 消息可回溯(一直存在)
- 一个消息可以被多个消费者读取
- 可以阻塞读取
- 又漏读消息的风险
基于 Stream 的消息队列之消费者组
消费者组:将多个消费者划分到一个组内,监听同一个队列
作用:
- 消息分流,分流到不同消费者加快处理,而非重复发送
- 消息标示:消费者组维护一个标示,记录最后一个被处理的消息,确保哪怕宕机重启,也不会漏读消息
- 消息确认:消费者获取消息后,消息将处于 pending 状态,并存入一个 pending-list 中,当处理完成后需要通过 XACK 确认消息,标记消息未已处理,才会将其从 pending-list 中移除
消费者组常用命令: XGROUP CREATE key groupName ID [MKSTREAM]

image.png|500

image.png|500
Redis 消息队列总结对比

image.png|500