这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
今天学习的是字节跳动青训营掘金内部课的中间件课程,了解了什么是中间件,还有一些消息队列
其中我发现,redis这种nosql数据库也是能做中间件的,起到当消息队列的作用
下面就是我总结的基于redis实现的消息队列
一、认识消息队列
消息队列,字面意思就存放消息的队列。
最简单的消息队列模型包括3个角色:
- 消息队列:存储和管理消息,也被称为消息代理
- 生产者:发送消息到消息队列
- 消费者:从消息队列获取消息并处理消息
解决了jvm堵塞队列内存不足的问题,而且消息队列是可以持久化的,宕机了依然能够保存。
redis提供三种不同方式实现消息队列:
- list结构:基于list结构模拟消息队列
- PubSub:基于的点对点消息队列
- Stream:比较完善的消息队列模型(推荐)
二、List模拟消息队列
redis的list结构是一个双向链表,很容易模拟出队列效果 队列是入口和出口不在一边,因此可以用LPUSH结合RPOP、或者RPUSH结合LPOP实现 但是,当队列没有消息时pop就会返回null,并不会jvm堵塞队列那样堵塞并等待消息,因此这里应该使用BRPOP或者BLPOP来实现堵塞队列。
缺点:
- 无法避免消息丢失。从消息队列取到消息,还没来得及处理就挂掉了,这个消息就消失了。
- 只支持单消费者。一个人拿走就从队列里面弹出了。
三、PubSub的消息队列
**PubSub(发布订阅)**是redis2.0版本引入的消息传递模型,消费者可以订阅一个或多个channel(频道),生产者向对应channel发送消息后,所有订阅者都能收到相关消息。
支持多生产、多消费
缺点:
- 不支持数据持久化(刚刚的list本质是做存储的我们拿来当队列所以可以持久化)
- 无法避免消息丢失。
- 消息堆积有上限,超出时数据丢失。(缓存空间是有上限的)
四、Stream的消息队列(重点)
Stream是redis5.0引入的一种新数据类型,可以实现一个功能非常完善的消息队列。
1、单消费模式
特点:
- 消息可回溯。不消失永久保存在队列里。
- 一个消息可以被多个消费者读取。读完不消失的,可以多个读
- 可以堵塞读取
- 有消息漏读的风险
2、消费者组
消费者组(Consumer Group):将多个消费者划分到一个组,监听同一个队列。
stream类型消息队列的消费者组特点:
- 消息可回溯
- 可以多消费者争抢消息,加快消费速度
- 可以阻塞读取
- 没有消息漏镀的风险
- 有消息确认机制,保证消息至少被消费一次
总结
消息队列中间件有很多,mq,卡夫卡等等,我们不一定要用这些,有时候redis也是可以当消息队列的,我们要根据公司的环境和业务实际情况来选择合适的中间件当做消息队列。这样才能更好的提高系统和接口的性能。