图灵奖得主弗雷德里克·布鲁克斯(Frederick P.Brooks Jr.)在他的经典著作《人月神话》中提出了“没有银弹”的观点,在软件工程中,每一个软件系统,都具有独特性,不存在像“银弹”一样的解决方案,可以解决一切问题。
对于消息队列来说也是一样的,我们常用的消息队列技术选型,都有各自的优势和劣势,我们需要根据自己的应用场景,选择合适的消息队列解决方案。
消息队列选择标准
抛开不同的消息队列在功能和特性上的区别,当我们做消息队列技术选型时,有一些通用的标准需要考虑。
消息队列产品是开源的,这样如果有一天使用消息队列时遇到一个影响业务功能的Bug,我们还可以通过修改源代码迅速修复。
消息队列产品是比较流行并且有一定活跃度的社区,这样只要你的应用场景不是特别冷门,那么你在使用过程中遇到的问题,基本是别人也会遇到并且已经修复的。
一款合格的消息队列产品还需要具备以下特性:
消息的可靠传递,确保不丢消息。
支持集群,确保不会因为某个节点宕机导致服务不可用。
具有良好的性能,满足绝大多数场景需求。
常见的消息队列产品
我们主要讨论三个常见的消息队列产品:
RabbitMQ
RocketMQ
Kafka
RabbitMQ
RabbitMQ是一个轻量级的消息队列,它使用Erlang语言编写,最早是为电信行业系统之间的可靠通信设计的,官网地址:https://www.rabbitmq.com/。
RabbitMQ一个有特色的功能是支持非常灵活的路由配置,它在生产者和队列之间增加了Exchange模块,可以根据配置的路由规则将生产者发出的消息发到不同的队列中,路由规则可以非常灵活,甚至我们可以自己来实现路由规则。
RabbitMQ的客户端支持很多不同的编程语言,如果我们的应用使用的编程语言比较冷门,那么很有可能你能找到对应语言的RabbitMQ客户端。
RabbitMQ存在3个问题:
RabbitMQ对消息堆积的支持不好,它的设计理念是消息队列是一个管道,大量的消息积压是一种不正常的情况,应当去避免。
RabbitMQ的性能是我们考察的三个消息队列产品中最差的,它每秒可以处理几万到十几万条消息,如果我们的应用场景对消息队列的性能要求非常高,那么RabbitMQ就不是合适的选择。
RabbitMQ使用的变成语言是Erlang,这个编程语言不仅小众,而且学习曲线很陡峭。
RocketMQ
RocketMQ是阿里巴巴在2012年开源的消息队列产品,后来捐赠给Apache软件基金会,2017年正式毕业,称为Apache的顶级项目。RocketMQ的官网地址:https://rocketmq.apache.org/。
RocketMQ使用Java语言编写,它有非常活跃的中文社区,你遇到的大多数问题都可以找到中文的答案。
RocketMQ对在线业务的响应时延做了大量优化,大多数情况下可以做到毫秒级响应,如果我们的应用场景中时延响应非常重要,那么可以选择RocketMQ。
RocketMQ的性能要比RabbitMQ高一个数量级,每秒钟可以处理几十万条消息。
RocketMQ的一个劣势是它在国外没有那么流行,与周边生态系统集成和兼容稍微差一些。
Kafka
Kafka最早由LinkedIn开发,目前也是Apache的顶级项目,官网地址:https://kafka.apache.org/
Kafka目前已经是一个非常成熟的消息队列产品,无论是在数据可靠性、稳定性还是功能特性等方面都可以满足绝大多数场景的需求。
Kafka使用Scala和Java语言开发,设计上大量使用了批量和异步的思想,这样可以让Kafka做到高性能,Kafka的性能,特别是异步收发的性能,是这三款消息队列产品中最好的。它在性能上和RocketMQ没有数量级上的差别,每秒钟可以处理几十万条消息。
Kafka与周边生态系统的兼容性是最好的没有之一,尤其是在大数据和流计算领域,几乎所有的相关开源软件都会优先选择支持Kafka。
Kafka存在的问题是同步收发消息的响应时延比较高,当客户端发送一条消息时,Kafka并不会立即发送出去,而是要等一会儿攒在一批再统一发送,在它的Broker中很多地方还存在“攒一波再处理”的设计,当我们的业务场景中每秒钟的消息数量没有那么多时,Kafka的时延反而会比较高,因此,Kafka不太适合在线业务场景。
其他消息队列
除了上述三款比较流行的消息队列产品,我们还可以看一下处于“第二梯队”的消息队列产品,包括:
ActiveMQ
ZeroMQ
ActiveMQ
ActiveMQ是最老牌的消息队列,目前已经进入老年期,社区不活跃,它存在的主要意义仅限于兼容哪些还在用的软件系统。
ActiveMQ的官网地址:https://activemq.apache.org/。
ZeroMQ
ZeroMQ严格意义上讲不是一个消息队列,而是基于消息队列的多线程网络库,如果我们的应用场景需要将消息队列的功能集成到系统进程中,可以考虑使用ZeroMQ。
ZeroMQ的官网地址:https://zeromq.org/。
Pulsar的官网地址:https://pulsar.apache.org/。
如何选择合适的消息队列产品?
结合上面描述的各个消息队列产品,我们可以得出下面的建议。
如果消息队列不是我们将要构建的系统的关键组件,而且我们对性能也没有很高的要求,只是需要一个开箱即用易于维护的产品,那么可以选择RabbitMQ。
如果我们的应用场景是处理在线业务,那么RocketMQ的低延迟和金融级的稳定性是我们需要的。
如果我们需要处理海量消息,或者我们场景中使用了大数据、流计算等开源产品,那么Kafka是最合适的消息队列。