消息队列
- 异步消息队列
- 延迟消息队列
以下内容为异步队列介绍
what
- 消息是两个服务之间沟通的媒介
- 消息可以有很多种,简单到字符串(如短信信息),也可以是对象
- 队列就是两个服务之间进行沟通的消息的容器或者载体
- 队列就是排队中的一组消息数据
- 队列就是一组有序的消息数据
- 队列可以是数组array,也可以是链表list,也可以是有序集合,只要该数据能承载消息并且有顺序
- 常见的队列大部分是基于链表的list
why
- 常用于解决并发系统中的资源一致性问题(如超卖)
- 提升峰值的处理能力,同时保证消息的顺序性、可恢复性、必送达性
who
- mysql
- redis
- 基于list的
lpush+rpop
实现的生产/消费模式 - 基于
pub/sub
的发布/订阅模式 - 基于
SortedSet
有序集合的实现 - 基于
Stream
类型的实现 - 专业消息中间件
- RabbitMQ
- Kafka
when
- 高并发,大流量
- 耗时特别长同时还不需要立即返回处理结果(异步处理)
where
- 流量削峰(如秒杀)
- 应用解耦(如订单系统和库存系统)
- 异步通信(发送短信、邮件)
- 顺序性(热点数据排序)
How
- 基于list的
lpush+rpop
实现的生产/消费模式 - 基于
pub/sub
的发布/订阅模式 - 基于
SortedSet
有序集合的实现 - 基于
Stream
类型的实现 - RabbitMQ
- Kafka
How feel
指标 比较 可靠性 rabbitMq > mysql > redis 性能 redis> rabbitMq > mysql 复杂度 rabbitMq > mysql > redis
因此,我们常用选型如下
- 如果对性能要求较高或者对安全可靠性要求不高的情形下,优先考虑基于redis实现队列
- 如果对消息的可靠性要求较高并且对性能兼顾的情况下,优先考虑专业消息中间件
- mysql消息中间件很少用到
redis实现异步消息分析
基于list的lpush+rpop
实现的生产/消费模式
优点:
- 低延迟(消息几乎无延迟)
缺点:
- 做消费者确认ACK麻烦,不能保证消费者消费消息后是否成功处理的问题(宕机或处理异常等),通常需要维护一个Pending列表,保证消息处理确认。
- 不能做广播模式,如pub/sub,消息发布/订阅模型
- 不能重复消费,一旦消费就会被删除
- 不支持分组消费
基于pub/sub
的发布/订阅模式
此模式允许生产者只生产一次消息,由中间件负责将消息复制到多个消息队列,每个消息队列由对应的消费组消费。
优点
- 典型的广播模式,一个消息可以发布到多个消费者
- 多信道订阅,消费者可以同时订阅多个信道,从而接收多类消息
- 消息即时发送,消息不用等待消费者读取,消费者会自动接收到信道发布的消息
缺点
- 消息一旦发布,不能接收。换句话就是发布时若客户端不在线,则消息丢失,不能寻回
- 不能保证每个消费者接收的时间是一致的
- 若消费者客户端出现消息积压,到一定程度,会被强制断开,导致消息意外丢失。通常发生在消息的生产远大于消费速度时
可见,Pub/Sub 模式不适合做消息存储,消息积压类的业务,而是擅长处理广播,即时通讯,即时反馈的业务。
基于SortedSet
有序集合的实现
优点
- 可以自定义消息ID,在消息ID有意义时,比较重要。
缺点
- 不允许重复消息(因为是集合),同时消息ID确定有错误会导致消息的顺序出错。
基于 Stream
类型的实现
TODO