基于JVM的阻塞队列实现的异步秒杀问题:
内存限制问题
数据安全问题
1、消息队列引入
使用队列的好处在于 **解耦:**所谓解耦,举一个生活中的例子就是:快递员(生产者)把快递放到快递柜里边(Message Queue)去,我们(消费者)从快递柜里边去拿东西,这就是一个异步,如果耦合,那么这个快递员相当于直接把快递交给你,这事固然好,但是万一你不在家,那么快递员就会一直等你,这就浪费了快递员的时间,所以这种思想在我们日常开发中,是非常有必要的。
这种场景在我们秒杀中就变成了:我们下单之后,利用redis去进行校验下单条件,再通过队列把消息发送出去,然后再启动一个线程去消费这个消息,完成解耦,同时也加快我们的响应速度。
2、基于Redis的List结构模拟消息队列(5种基本数据类型之一)
List:双向链表
基于List的消息队列有哪些优缺点?
优点:
* 利用Redis存储,不受限于JVM内存上限
* 基于Redis的持久化机制,数据安全性有保证 做数据存储的数据结构都支持持久化
* 可以满足消息有序性
缺点:
* 无法避免消息丢失
* 只支持单消费者
3、基于Redis的LPubSub结构消息队列(专门的发布订阅机制)
PSUBSCRIBE:pattern
基于PubSub的消息队列有哪些优缺点?
优点:
* 采用发布订阅模型,支持多生产、多消费
缺点:
发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息
* 不支持数据持久化 本身就是订阅发布机制,不同于基础数据存储数据类型,故而不支持持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃
* 无法避免消息丢失 无消费者订阅,channel的消息会丢失
* 消息堆积有上限,超出时数据丢失 如果有消费者监听,消息会存储至消费者的缓存区域(有上限)
4、基于Redis的Stream数据类型消息队列(也是一个数据类型,故而支持持久化)
Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
消息读完不会被删除