1.什么叫消息队列
消息队列,就是指保存消息的一个容器。具体的定义这里就不类似于数据库、 缓存等,用来保存数据的。 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复 杂,可能包含嵌入对象,消息队列(
Message Queue
)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保
消息的可靠传递。消息发布者只管把消息发布到
MQ
中而不用管谁来取,消息使用者只管从
MQ
中取消
息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
2.为什么要用消息队列
消息队列是一种应用间的异步协作机制,那什么场景下需要使用 MQ
呢? 以常见的订单系统为例,用户点击下单之后的业务逻辑可能包括:扣减库存、生成相应单据、 发红包、发短信通知。在业务发展初期这些逻辑可能放在一起同步执行,随着业务的发展订单量增长, 需要提升系统服务的性能,这时可以将一些不需要立即生效的操作拆分出来异步执行,比如发放红包、
发短信通知等。这种场景下就可以用
MQ
,在下单的主流程(比如扣减库存、生成相应单据)完成之后 发送一条消息到 MQ
让主流程快速完结,而由另外的单独线程拉取
MQ
的消息(或者由
MQ
推送消 息),当发现 MQ
中有发红包或发短信之类的消息时,执行相应的业务逻辑。 以上是用于业务解耦的情况,其它常见场景包括最终一致性、广播、错峰流控等等
3.消息队列的分类以及应用场景
现在常用的MQ
组件有
activeMQ
、
rabbitMQ
、
rocketMQ
、
zeroMQ
,当然近年来火热的
kafka
,从某些 场景来说,也是MQ
,当然
kafka
的功能更加强大,虽然不同的
MQ
都有自己的特点和优势,但是,不管是哪种MQ
,都有
MQ
本身自带的一些特点。
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题。下面会介绍某些应用场景并举例
3.1异步处理
业务场景是用户注册后,需要发注册邮件和注册短信
传统的做法有两种
1.
串行的方式;
2.
并行方式
串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成 后,返回给客户端。
串行的方式
并行的方式
并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成 后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间
使用MQ解耦的方式
![](https://img-blog.csdnimg.cn/8a4fec1b8bd5431b84019538ccae586e.png)
3.2应用解耦
场景说明:用户下单后,订单系统需要通知库存系统
传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合,如何解决这个问题呢?答案就是引入消息队列进行解耦
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
库存系统:订阅下单的消息,采用拉
/
推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不 再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。
3.3流量削峰
流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛, 秒杀活动一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。 控制活动的人数,缓解短时间内高流量压垮应用。
![](https://img-blog.csdnimg.cn/ecb5f19a22a24d819613915dfc83f908.png)
用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请 求或跳转到错误页面。 秒杀业务根据消息队列中的请求信息,再做后续处理
4.消息队列的特点
先进先出,
消息队列的顺序在入队的时候就基本已经确定了,一般是不需人工
干预的。 发布订阅,发布订阅是一种很高效的处理方式,如果不发生阻塞,基本可以当做是同步操作。这种处理方式能非常有效的提升服务器利用率,应用场景非常广泛。
分布式,
在现在大流量、大数据的使用场景下,只支持单体应用的服务器软件基本是无法使用的,支持分布式的
部署,才能被广泛使用。而且,
MQ
的定位就是一个高性能的中间件。
持久化,持久化确保
MQ
的使用不只是一个部分场景的辅助工具,而是让
MQ
能像数据库一样存储核心的数据。
5.常用的消息队列比较
![](https://img-blog.csdnimg.cn/a0397b915b194f85a675179d66636378.png)
总体来说:
ActiveMQ
历史悠久的开源项目,已经在很多产品中得到应用,实现了
JMS1.1
规范,可以和
spring-jms 轻松融合,实现了多种协议,不够轻巧(源代码比RocketMQ
多),支持持久化到数据库,对队列数较 多的情况支持不好。
RabbitMQ
它比
Kafka
成熟,支持
AMQP
事务处理,在可靠性上,
RabbitMQ
超过
Kafka
,在性能方面超 过ActiveMQ
。
RocketMQ RocketMQ
是阿里开源的消息中间件,目前在
Apache
孵化,使用纯
Java
开发,具有高吞吐 量、高可用性、适合大规模分布式系统应用的特点。RocketMQ
思路起源于
Kafka
,但并不是简单的复 制,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息 推送、日志流式处理、binglog
分发等场景,支撑了阿里多次双十一活动。 因为是阿里内部从实践到产 品的产物,因此里面很多接口、API
并不是很普遍适用。其可靠性毋庸置疑,而且与
Kafka
一脉相承(甚 至更优),性能强劲,支持海量堆积。
·
Kafka Kafka
设计的初衷就是处理日志的,不支持
AMQP
事务处理,可以看做是一个日志系统,针对性 很强,所以它并没有具备一个成熟MQ
应该具备的特性。
Kafka
的性能(吞吐量、
tps
)比
RabbitMQ
要 强,如果用来做大数据量的快速处理是比RabbitMQ
有优势的