为何要使用消息队列
在高并发业务场景下,消息队列在架构设计中至关重要,特别是在异步处理、削峰、解耦上有不可替代的作用。目前较为流行的消息队列中间件有Kafka、ZeroMQ、RabbitMQ、RocketMQ、ActiveMQ、Pulsar 等。那么,消息队列中间件这么多,系统架构设计时,到底该如何选型呢?
选择消息队列的基本要求
1.开源产品优先,并且该产品的社区活跃度较高,社区活跃度高意味着使用的人多,产品在出现bug时,不仅能得到很快的修复,而且前人前人踩过的坑,你不必重蹈覆辙了。另外,在选择开源产品时,不要选用该产品的最新版本,一般选择较为稳定的版本。
2.可替代性,任何消息队列中间件都可能不是最佳的技术选型,架构设计时,我们要考虑备选方案。选择的中间件可替代,尽可能地做到出现问题时,能快速切换到备选方案,实现动态插拔,无代码入侵。
3.从中间件本身支持高可用、可靠传递、持久化、高性能的程度上进行考虑。
4.从团队的整体技术能力、学习成本、易用性、可操作性上进行考虑,选择更适合团队开发成员的消息中间件。
5.从产品的运维部署方面进行考虑,选择运维部署方便、可扩展能力强、监控跟踪方便的消息中间件。
几款常用的消息队列中间件对比
一、RabbitMQ

RabbitMQ ,使用 Erlang 编程语言编写的,发布于2007年,最早用于电信行业系统之间的可靠通信,支持 AMQP 协议的消息。
优点:
- 开箱即用,是一个相当轻量级的消息队列,部署和使用都非常容易。
- RabbitMQ 有着非常灵活的路由配置,它通过交换机(Exchange) ,根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至可以自己来实现路由规则。
- 客户端支持多种编程语言进行对接。
- RabbitMQ 客户端支持的编程语言大概是所有消息队列中最多的。
缺点:
- 对消息堆积的支持不好,当大量消息堆积时,会导致其性能急剧下降。
- 性能相比其他中间件而言,不太理想,大概每秒钟可以处理几万到十几万条消息。
- 使用 Erlang 编程语言,扩展和二次开发成本高。
二、RocketMQ

RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了一些改进,后来捐赠给 Apache 软件基金会,成为 Apache 的顶级项目。RocketMQ 在阿里内部被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,Binglog 分发等场景。经历过多次双十一考验,它的性能、稳定性和可靠性都是值得信赖的。
优点:
- 有着不错的性能,稳定性和可靠性。
- 在非常活跃的中文社区,大多数问题可以找到中文的答案。
- 使用 Java 语言开发,源代码相对比较容易读懂,容易对 RocketMQ 进行扩展或者二次开发。
- 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应。
- 性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息。
缺点:
- 与周边生态系统的集成和兼容程度不够。
三、Kafka

Apache Kafka 是一个分布式消息发布订阅系统。它最初由 LinkedIn 公司基于独特的设计实现为一个分布式的日志提交系统,之后成为 Apache 项目的一部分。在早期的版本中,为了获得极致的性能,在设计方面做了很多的牺牲,比如不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋,这些牺牲对于处理海量日志这个特定的场景都是可以接受的。
优点:
- 性能高效、可扩展良好并且可持久化。它的分区特性,可复制和可容错都是不错的特性。
- Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,使得 Kafka 能够做到超高的性能。Kafka 的性能,尤其是异步收发的性能,是三者中最好的,但与 RocketMQ 并没有量级上的差异,大约每秒钟可以处理几十万条消息。
- 在有足够的客户端并发进行异步批量发送,并且开启压缩的情况下,Kafka 的极限处理能力可以超过每秒 2000 万条消息。
- 与周边生态系统的兼容性是最好的,尤其在大数据和流量计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka。
缺点:
- Kafka不太适合在线业务场景。
- 异步批量的设计存在问题,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息的时候,Kafka 并不会立即发送出去,而是要等一会儿攒一批再发送。
总结
系统架构设计中,对于高并发场景下的消息队列及相关技术选型,可以参考以下几条建议:
- 如果对于功能和性能没有很高的要求,建议使用 RabbitMQ,因为它是一个快速上手和易于维护的消息队列。
- 如果系统主要业务场景是处理在线业务,比如订单传递,消息通知等,性能指标方面需要低延迟和高稳定性,建议使用 RocketMQ。
- 如果需要处理海量的系统采集日志、监控信息,或是你的应用场景大量使用了大数据、流式计算相关的产品,那么建议使用 Kafka,因为它与周边的生态系统兼容比较好。
