消息队列(Message Queue)有下面四大作用:
- 解耦。几个业务系统之间可以通过 MQ 解耦,例如做数据同步
- 数据的顺序性和可恢复性
- 异步通讯
- 缓冲能力
MQ_7">理解 MQ
MQ 的前两个特点且不说,我们看看另外两个的。
MQ__RPC__10">异步通讯: MQ 与 RPC 区别
从 MQ 与 RPC 区别的切入,可以很好地理解 MQ 的异步能力。
首先,我们了解到 RPC(远程过程调用)通信本质上是一个同步过程,这就意味着在 RPC 方法调用期间,当前执行线程必须等待方法调用完全结束才能继续执行后续的操作。这种等待会增加系统的延迟,并可能影响用户体验,特别是在高并发场景下。
相比之下,消息队列采用的是天然的异步通信模式,即发送者和接收者之间可以独立地发送和接收消息,这种方式有效地解决了 RPC 在异步性和用户体验上的局限性。不过,异步通信模式也引入了额外的复杂性,比如需要处理消息传递的可靠性和顺序等问题。
正因为如此,在现代的大规模分布式系统中,通常会结合使用 RPC 和消息队列这两种通信机制,以此来平衡系统的性能需求和复杂度,同时解决多进程间的通信问题。
缓冲能力
消息队列的另一个关键特性是其出色的缓冲能力。由于消息队列可以配置成具有非常大的存储容量,尤其是在使用磁盘存储的情况下,几乎可以视为拥有无限的存储空间。这使得在流量高峰时段,系统能够暂时存储大量涌入的消息,然后在后续较低峰的时段内逐步处理这些消息,从而避免了因瞬时负载过大而导致的服务中断或系统崩溃。
例如,在电子商务网站进行限时抢购活动时,这类场景通常伴随着极高的瞬间流量冲击。此时,消息队列的高容量缓冲功能就显得尤为重要,它能够有效地吸收这股“洪峰”,确保系统的稳定运行。以下是一个简化版的秒杀业务UML序列图,展示了在这个场景中如何通过引入消息队列来解决问题。消息队列就像是一个巨大的缓冲池,可以吸收大量的并发请求,并且基本上保持了请求的原始顺序。接着,后端的服务(可能是部署在多台服务器上的)可以从容地处理队列中的秒杀请求(实现先到先得的原则),并将成功抢购的结果记录到数据库中以备查询。
MQ__26">MQ 发展情况
市场上现有的消息队列产品,可以根据它们的发展阶段和技术先进性分为三个世代。
第一代消息队列起源于 J2EE 时代,它们主要关注企业级特性,例如消息的持久化存储和事务支持,这些产品通常遵循 JMS 规范。这一时期的消息中间件一般作为 J2EE 套件的一部分出售。然而,随着 J2EE 时代的逐渐淡出,多数商业消息中间件已经逐渐被淘汰。在开源领域,仅剩少数几个项目仍在活跃,其中最为人所知的就是 Apache 的 ActiveMQ 和 JBoss 的 HornetQ。后来,JBoss 将 HornetQ 的源代码捐赠给了 Apache ActiveMQ 项目组,双方共同开发了 ActiveMQ Artemis。从2016年起,JBoss EAP7 企业版开始使用 ActiveMQ Artemis 替代之前的 HornetQ,而 RedHat 的 JBoss A-MQ 也基于 ActiveMQ 构建。尽管现在基于 J2EE 架构的应用减少了,但仍有部分重要商业软件依赖于这些传统消息队列。据 Gartner 报告显示,IBM MQ 在2016年占据了66%的市场份额。
第二代消息队列是在 Java 时代之后出现的。由于 Java 时代的中间件市场被 IBM 和 Tibco 主导,缺乏开放性和竞争,因此出现了一些试图打破这种局面的“挑战者”。这些团体推动了 AMQP(高级消息队列协议)的发展,这是一种开放的标准,旨在鼓励更多厂商实现兼容 AMQP 的产品。这一努力取得了成功,RabbitMQ 成为首个知名的支持 AMQP 的开源产品,自2007年发布以来,已成为最流行的消息队列之一。此外,AMQP 的普及还促进了 Java 领域的变革,例如 Apache 的 Qpid 项目支持 AMQP 协议,并提供了多种语言的支持,而 ActiveMQ 也在2013年开始支持 AMQP。
第三代消息队列是互联网时代的产物,它们的设计理念更为现代化,通常采用分布式架构,并利用 ZooKeeper 进行集群管理。这一代的代表产品是 LinkedIn 开源的 Kafka,它以其出色的可扩展性和高性能著称。Kafka 适用于多种数据管道和消息系统,许多重要的分布式处理框架如 Cloudera、Apache Storm 和 Spark 都支持与 Kafka 集成。在国内,一些公司也借鉴了 Kafka 的设计,如搜狐的 Jafka 和阿里巴巴的 RocketMQ。RocketMQ 在阿里巴巴内部被广泛应用,并于2012年开源。尽管开源后的维护一度停滞,但在2016年,阿里巴巴将其捐赠给 Apache 后,仍继续开发闭源版本并在阿里云上作为付费服务提供。