系统学习消息队列分享(三) 该如何选择消息队列?

聊一下几个比较常见的开源的消息队列中间件。若是你正在作消息队列技术选型,不知道该选择哪款消息队列,你必定要先听一下这节课的内容。前端

做为一个程序员,相信你必定听过“没有银弹”这个说法,这里面的银弹是指能轻松杀死狼人、用白银作的子弹,什么意思呢?我对这句话的理解是说,在软件工程中,不存在像“银弹”这样能够解决一切问题的设计、架构或软件,每个软件系统,它都是独一无二的,你不可能用一套方法去解决全部的问题。程序员

在消息队列的技术选型这个问题上,也是一样的道理。并不存在说,哪一个消息队列就是“最好的”。经常使用的这几个消息队列,每个产品都有本身的优点和劣势,你须要根据现有系统的状况,选择最适合你的那款产品。编程

选择消息队列产品的基本标准

虽然这些消息队列产品在功能和特性方面各有优劣,但咱们在选择的时候要有一个最低标准,保证入选的产品至少是及格的。服务器

接下来咱们先说一下这及格的标准是什么样的。网络

首先,必须是开源的产品,这个很是重要。开源意味着,若是有一天你使用的消息队列遇到了一个影响你系统业务的 Bug,你至少还有机会经过修改源代码来迅速修复或规避这个 Bug,解决你的系统迫不及待的问题,而不是一筹莫展地等待开发者不必定何时发布的下一个版原本解决。多线程

其次,这个产品必须是近年来比较流行而且有必定社区活跃度的产品。流行的好处是,只要你的使用场景不太冷门,你遇到 Bug 的几率会很是低,由于大部分你可能遇到的 Bug,其余人早就遇到而且修复了。你在使用过程当中遇到的一些问题,也比较容易在网上搜索到相似的问题,而后很快的找到解决方案。架构

还有一个优点就是,流行的产品与周边生态系统会有一个比较好的集成和兼容,好比,Kafka 和 Flink 就有比较好的兼容性,Flink 内置了 Kafka 的 Data Source,使用 Kafka 就很容易做为 Flink 的数据源开发流计算应用,若是你用一个比较小众的消息队列产品,在进行流计算的时候,你就不得不本身开发一个 Flink 的 Data Source。并发

最后,做为一款及格的消息队列产品,必须具有的几个特性包括:异步

  • 消息的可靠传递:确保不丢消息;
  • Cluster:支持集群,确保不会由于某个节点宕机致使服务不可用,固然也不能丢消息;
  • 性能:具有足够好的性能,能知足绝大多数场景的性能要求。

接下来咱们一块儿看一下有哪些符合上面这些条件,可供选择的开源消息队列产品。编程语言

可供选择的消息队列产品

1. RabbitMQ

首先,咱们说一下老牌儿消息队列 RabbitMQ,俗称兔子 MQ。RabbitMQ 是使用一种比较小众的编程语言:Erlang 语言编写的,它最先是为电信行业系统之间的可靠通讯设计的,也是少数几个支持 AMQP 协议的消息队列之一。

RabbitMQ 就像它的名字中的兔子同样:轻量级、迅捷,它的 Slogan,也就是宣传口号,也很明确地代表了 RabbitMQ 的特色:Messaging that just works,“开箱即用的消息队列”。也就是说,RabbitMQ 是一个至关轻量级的消息队列,很是容易部署和使用。

另外 RabbitMQ 还号称是世界上使用最普遍的开源消息队列,是否是真的使用率世界第一,咱们没有办法统计,但至少是“最流行的消息中间之一”,这是没有问题的。

RabbitMQ 一个比较有特点的功能是支持很是灵活的路由配置,和其余消息队列不一样的是,它在生产者(Producer)和队列(Queue)之间增长了一个 Exchange 模块,你能够理解为交换机。

这个 Exchange 模块的做用和交换机也很是类似,根据配置的路由规则将生产者发出的消息分发到不一样的队列中。路由的规则也很是灵活,甚至你能够本身来实现路由规则。基于这个 Exchange,能够产生不少的玩儿法,若是你正好须要这个功能,RabbitMQ 是个不错的选择。

RabbitMQ 的客户端支持的编程语言大概是全部消息队列中最多的,若是你的系统是用某种冷门语言开发的,那你多半能够找到对应的 RabbitMQ 客户端。

接下来讲下 RabbitMQ 的几个问题。

第一个问题是,RabbitMQ 对消息堆积的支持并很差,在它的设计理念里面,消息队列是一个管道,大量的消息积压是一种不正常的状况,应当尽可能去避免。当大量消息积压的时候,会致使 RabbitMQ 的性能急剧降低。

第二个问题是,RabbitMQ 的性能是咱们介绍的这几个消息队列中最差的,根据官方给出的测试数据综合咱们平常使用的经验,依据硬件配置的不一样,它大概每秒钟能够处理几万到十几万条消息。其实,这个性能也足够支撑绝大多数的应用场景了,不过,若是你的应用对消息队列的性能要求很是高,那不要选择 RabbitMQ。

最后一个问题是 RabbitMQ 使用的编程语言 Erlang,这个编程语言不只是很是小众的语言,更麻烦的是,这个语言的学习曲线很是陡峭。大多数流行的编程语言,好比 Java、C/C++、Python 和 JavaScript,虽然语法、特性有不少的不一样,但它们基本的体系结构都是同样的,你只精通一种语言,也很容易学习其余的语言,短期内即便作不到精通,但至少能达到“会用”的水平。

就像一个以英语为母语的人,学习法语、德语都很容易,可是你要是让他去学汉语,那基本上和学习其余这些语言不是一个难度级别的。很不幸的是,Erlang 就是编程语言中的“汉语”。因此若是你想基于 RabbitMQ 作一些扩展和二次开发什么的,建议你慎重考虑一下可持续维护的问题。

2. RocketMQ

RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。阿里内部也是使用 RocketMQ 做为支撑其业务的消息队列,经历过屡次“双十一”考验,它的性能、稳定性和可靠性都是值得信赖的。做为优秀的国产消息队列,近年来愈来愈多的被国内众多大厂使用。

我在总结 RocketMQ 的特色时,发现很难找出 RocketMQ 有什么特别让我印象深入的特色,也很难找到它有什么缺点。

RocketMQ 就像一个品学兼优的好学生,有着不错的性能,稳定性和可靠性,具有一个现代的消息队列应该有的几乎所有功能和特性,而且它还在持续的成长中。

RocketMQ 有很是活跃的中文社区,大多数问题你均可以找到中文的答案,也许会成为你选择它的一个缘由。另外,RocketMQ 使用 Java 语言开发,它的贡献者大多数都是中国人,源代码相对也比较容易读懂,你很容易对 RocketMQ 进行扩展或者二次开发。

RocketMQ 对在线业务的响应时延作了不少的优化,大多数状况下能够作到毫秒级的响应,若是你的应用场景很在乎响应时延,那应该选择使用 RocketMQ。

RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息。

RocketMQ 的一个劣势是,做为国产的消息队列,相比国外的比较流行的同类产品,在国际上尚未那么流行,与周边生态系统的集成和兼容程度要略逊一筹。

3. Kafka

最后咱们聊一聊 Kafka。Kafka 最先是由 LinkedIn 开发,目前也是 Apache 的顶级项目。Kafka 最初的设计目的是用于处理海量的日志。

在早期的版本中,为了得到极致的性能,在设计方面作了不少的牺牲,好比不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋,这些牺牲对于处理海量日志这个特定的场景都是能够接受的。这个时期的 Kafka 甚至不能称之为一个合格的消息队列。

可是,请注意,重点通常都在后面。随后的几年 Kafka 逐步补齐了这些短板,你在网上搜到的不少消息队列的对比文章还在说 Kafka 不可靠,其实这种说法早已通过时了。当下的 Kafka 已经发展为一个很是成熟的消息队列产品,不管在数据可靠性、稳定性和功能特性等方面均可以知足绝大多数场景的需求。

Kafka 与周边生态系统的兼容性是最好的没有之一,尤为在大数据和流计算领域,几乎全部的相关开源软件系统都会优先支持 Kafka。

Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,这种设计使得 Kafka 能作到超高的性能。Kafka 的性能,尤为是异步收发的性能,是三者中最好的,但与 RocketMQ 并无量级上的差别,大约每秒钟能够处理几十万条消息。

我曾经使用配置比较好的服务器对 Kafka 进行过压测,在有足够的客户端并发进行异步批量发送,而且开启压缩的状况下,Kafka 的极限处理能力能够超过每秒 2000 万条消息。

可是 Kafka 这种异步批量的设计带来的问题是,它的同步收发消息的响应时延比较高,由于当客户端发送一条消息的时候,Kafka 并不会当即发送出去,而是要等一下子攒一批再发送,在它的 Broker 中,不少地方都会使用这种“先攒一波再一块儿处理”的设计。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。因此,Kafka 不太适合在线业务场景。

第二梯队的消息队列

除了上面给你介绍的三大消息队列以外,还有几个第二梯队的产品,我我的的观点是,这些产品之因此没那么流行,或多或少都有着比较明显的短板,不推荐使用。在这儿呢,我简单介绍一下,纯当丰富你的知识广度。

先说 ActiveMQ,ActiveMQ 是最老牌的开源消息队列,是十年前惟一可供选择的开源消息队列,目前已进入老年期,社区不活跃。不管是功能仍是性能方面,ActiveMQ 都与现代的消息队列存在明显的差距,它存在的意义仅限于兼容那些还在用的爷爷辈儿的系统。

接下来讲说 ZeroMQ,严格来讲 ZeroMQ 并不能称之为一个消息队列,而是一个基于消息队列的多线程网络库,若是你的需求是将消息队列的功能集成到你的系统进程中,能够考虑使用 ZeroMQ。

最后说一下 Pulsar,不少人可能都没据说过这个产品,Pulsar 是一个新兴的开源消息队列产品,最先是由 Yahoo 开发,目前处于成长期,流行度和成熟度相对没有那么高。与其余消息队列最大的不一样是,Pulsar 采用存储和计算分离的设计,我我的很是喜欢这种设计,它有可能会引领将来消息队列的一个发展方向,建议你持续关注这个项目。

总结

在了解了上面这些开源消息队列各自的特色和优劣势后,我相信你对于消息队列的选择已经能够作到心中有数了。我也总结了几条选择的建议供你参考。

若是说,消息队列并非你将要构建系统的主角之一,你对消息队列功能和性能都没有很高的要求,只须要一个开箱即用易于维护的产品,我建议你使用 RabbitMQ。

若是你的系统使用消息队列主要场景是处理在线业务,好比在交易系统中用消息队列传递订单,那 RocketMQ 的低延迟和金融级的稳定性是你须要的。

若是你须要处理海量的消息,像收集日志、监控信息或是前端的埋点这类数据,或是你的应用场景大量使用了大数据、流计算相关的开源产品,那 Kafka 是最适合你的消息队列。

若是我说的这些场景和你的场景都不符合,你看了我以前介绍的这些消息队列的特色后,仍是不知道如何选择,那就选你最熟悉的吧,毕竟这些产品都能知足大多数应用场景,使用熟悉的产品还能够快速上手不是?

相关文章
相关标签/搜索