聊聊 MQ 技术选型

作者:微信小助手

发布时间:2022-05-27T20:32:40

消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题。它可以实现高性能、高可用、可伸缩和最终一致性架构,是大型分布式系统不可缺少的中间件。

消息队列在电商系统、消息通讯、日志收集等应用中扮演着关键作用,以阿里为例,其研发的消息队列(RocketMQ)在历次天猫 “双十一” 活动中支撑了万亿级的数据洪峰,为大规模交易提供了有力保障。

作为提升应用性能的重要手段,分布式消息队列技术在互联网领域得到了越来越广泛的关注 。本文将介绍四种常用的分布式消息队列开源软件:KafkaActiveMQRabbitMQRocketMQ

文章目录如下:

  • Kafka
  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • 几种消息队列的比较
  • 参考文献

1. Kafka

在分布式消息队列的江湖里,Kafka 凭借其优秀的性能占据重要一席。它最初由 LinkedIn 公司开发,Linkedin 于 2010 年贡献给了 Apache基金会,之后成为顶级开源项目。

Kafka简介

关于 Kafka,网上有很多介绍,经过不断地复制、洗稿、演绎后,难免背离原意,因此,我们还是来看一下官网给出的定义:

Apache Kafka is a distributed streaming platform.

Kafka 作为流平台具有以下三种能力:

  1. 发布和订阅记录流,类似于消息队列或企业消息系统;
  2. 具有容错能力,且可以持久化的方式存储记录流;
  3. 当记录流产生时(发生时),可及时对其进行处理。

Kafka 适用于两类应用:

  1. 建立实时流数据管道,在系统或应用之间可靠地获取数据;
  2. 建立对数据流进行转换或反应的实时流应用程序。

kafka 包含四种核心 API。

  • Producer API:基于该 API,应用程序可以将记录流发布到一个或多个 Kafka 主题(Topics);
  • Consumer API:基于该 API,应用程序可以订阅一个或多个主题,并处理主题对应的记录流;
  • Streams API:基于该 API,应用程序可以充当流处理器,从一个或多个主题消费输入流,并生成输出流输出一个或多个主题,从而有效地将输入流转换为输出流;
  • Connector API:允许构建和运行将 Kafka 主题连接到现有应用程序或数据系统的可重用生产者或消费者。例如,关系数据库的连接器可能会捕获表的每一个更改。

Kafka 特点

作为一种高吞吐量的分布式发布订阅消息系统,Kafka 具有如下特性:

  1. 快速持久化,可以在 O(1) 的系统开销下进行消息持久化;
  2. 高吞吐,在一台普通的服务器上可以达到 10W/s 的吞吐速率;
  3. 完全的分布式系统,Broker、Producer、Consumer 都原生自动支持分布式,自动实现负载均衡;
  4. 支持同步和异步复制两种 HA;
  5. 支持数据批量发送和拉取;
  6. Zero-Copy,减少 IO 操作步骤;
  7. 数据迁移、扩容对用户透明;
  8. 无需停机即可扩展机器;
  9. 其他特性还包括严格的消息顺序、丰富的消息拉取模型、高效订阅者水平扩展、实时的消息订阅、亿级的消息堆积能力、定期删除机制。

Kafka 部署环境

操作系统

  • Windows:虽然 Kafka 可以在部分 Windows 系统运行,但官方并不推荐;
  • Unix:支持所有版本的 Unix 系统,以及 Linux 和 Solaris系统。

环境要求

  • JDK:Kafka 的最新版本为 2.0.0,JDK 版本需 1.8 及以上;
  • ZooKeeper:Kafka 集群依赖 ZooKeeper,需根据 Kafka 的版本选择安装对应的 ZooKeeper 版本(未来的 Kafka 即将脱离 ZooKeeper)。

Kafka 架构

kafka架构

如上图所示,一个典型的 Kafka 体系架构包括若干 Producer(消息生产者),若干 Broker(Kafka 支持水平扩展,一般 Broker 数量越多,集群吞吐率越高),若干 Consumer(Group),以及一个 Zookeeper 集群。Kafka 通过 Zookeeper 管理集群配置,选举 Leader,以及在 Consumer Group 发生变化时进行 Rebalance。Producer 使用 Push(推)模式将消息发布到 Broker,Consumer 使用 Pull(拉)模式从 Broker 订阅并消费消息。

各个名词的解释请见下表:

Kafka 核心组件

Kafka 高可用方案

Kafka 高可用性的保障来源于其健壮的副本(Replication)策略。为了提高吞吐能力,Kafka 中每一个 Topic 分为若干 Partitions;为了保证可用性,每一个 Partition 又设置若干副本(Replicas);为了保障数据的一致性,Zookeeper 机制得以引入。基于 Zookeeper,Kafka 为每一个 Partition 找一个节点作为 Leader,其余备份作为 Follower,只有 Leader 才能处理客户端请求,而 Follower 仅作为副本同步 Leader 的数据,如下示意图:TopicA 分为两个 Partition,每个 Partition 配置两个副本。

Kafka 高可用方案

基于上图的架构,当 Producer Push 的消息写入 Partition(分区) 时,Leader 所在的 Broker(Kafka 节点)会将消息写入自己的分区,同时还会将此消息复制到各个 Follower,实现同步。如果某个 Follower 挂掉,Leader 会再找一个替代并同步消息;如果 Leader 挂了,将会从 Follower 中选举出一个新的 Leader 替代,继续业务,这些都是由 ZooKeeper 完成的。

Kafka 优缺点

优点主要包括以下几点:

  1. 客户端语言丰富,支持 Java、.NET、PHP、Ruby、Python、Go 等多种语言;
  2. 性能卓越,单机写入 TPS 约在百万条/秒,消息大小 10 个字节;
  3. 提供完全分布式架构,并有 Replica 机制,拥有较高的可用性和可靠性,理论上支持消息无限堆积;
  4. 支持批量操作;
  5. 消费者采用 Pull 方式获取消息,消息有序,通过控制能够保证所有消息被消费且仅被消费一次;
  6. 有优秀的第三方 Kafka Web 管理界面 Kafka-Manager;
  7. 在日志领域比较成熟,被多家公司和多个开源项目使用。

缺点主要有:

  1. Kafka 单机超过 64 个队列/分区,Load 会发生明显的飙高现象,队列越多,Load 越高,发送消息响应时间越长;
  2. 使用短轮询方式,实时性取决于轮询间隔时间;
  3. 消费失败不支持重试;
  4. 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
  5. 社区更新较慢。

2. ActiveMQ

ActiveMQ 是 Apache 下的一个子项目。之所以把它放在第二位介绍,是因为它官网上的说明:

Apache ActiveMQ is the most popular and powerful open source messaging and Integration Patterns server.

居然没有“之一”,不太谦虚呀,放在第二位,以示“诫勉”。

ActiveMQ 简介

ActiveMQ 由 Apache 出品,据官网介绍,它是最流行和最强大的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现,非常快速,支持多种语言的客户端和协议,而且可以非常容易地嵌入到企业的应用环境中,并有许多高级功能。

ActiveMQ 基于 Java 语言开发,目前最新版本为 5.1.5.6。

ActiveMQ 特点

ActiveMQ 的特点,官网在 Features 一栏中做了非常详细的说明,我做了下翻译,如下:

  1. 支持多种语言和协议编写客户端。语言包括 Java、C、C++、C#、Ruby、Perl、Python、PHP。应用协议包括 OpenWire、Stomp REST、WS Notification、XMPP、AMQP;
  2. 完全支持 JMS1.1 和 J2EE 1.4 规范(持久化、XA 消息、事务);
  3. 完全支持 JMS 客户端和消息代理中的企业集成模式;
  4. 支持许多高级特性,例如消息组、虚拟目的地、通配符和复合目的地;
  5. 支持 Spring,ActiveMQ 可以很容易地嵌入 Spring 应用程序中,并使用 Spring 的 XML 配置机制进行配置;
  6. 通过了常见 J2EE 服务器(如 Geronimo、JBoss4、GlassFish、WebLogic)的测试,其中通过 JCA 1.5 Resource Adaptors 的配置,可以让 ActiveMQ 自动部署到任何兼容 J2EE 1.4 商业服务器上;
  7. 支持多种传输协议,如 VM、TCP、SSL、NIO、UDP、Multicast、JGroups 以及 JXTA;
  8. 支持通过 JDBC 和 Journal 提供高速的消息持久化;
  9. 从设计上保证了高性能的集群,客户端-服务器,点对点;
  10. REST API 为消息提供技术无关和基于语言的 Web API;
  11. AJAX 允许使用纯 DHTML 实现 Web 流对 Web 浏览器的支持,允许 Web 浏览器成为消息传递结构的一部分;
  12. 获得 CXF 和 Axes 的支持,使得 ActiveMQ 可以很容易地嵌入 Web 服务栈中的任何一个,以提供可靠的消息传递;
  13. 很容易调用内嵌 JMS Provider,进行测试。

ActiveMQ 部署环境

相较于 Kafka,ActiveMQ 的部署简单很多,支持多个版本的 Windows 和 Unix 系统,此外,ActiveMQ 由 Java 语言开发而成,因此需要 JRE 支持。

硬件要求:

  • 如果以二进制文件安装,ActiveMQ 5.x 需要 60M 空间。当然,需要额外的磁盘空间来持久化消息;
  • 如果下载 ActiveMQ 5.x 源文件,自行编译构建, 则需要 300M 空间。

操作系统:

  • Windows:支持 Windows XP SP2、Windows 2000、Windows Vista、Windows 7;
  • Unix:支持 Ubuntu Linux、Powerdog Linux、MacOS、AIX、HP-UX、Solaris,或者其它任何支持 Java 的 Unix 平台。

环境要求:

  • Java 运行环境(JRE),版本 1.7 及以上,如果以源码自行编译构建,则还需要安装 JDK;
  • 需要为 JRE 配置环境变量,通常命名为 JAVA_HOME;
  • 如果以源文件自行编译构建,需安装 Maven 3.0.0 及以上版本,同时,依赖的 JAR 包需要添加到 classpath 中。

ActiveMQ 架构

ActiveMQ 的主体架构如下图所示。

ActiveMQ 架构

传输协议:消息之间的传递,无疑需要协议进行沟通,启动一个 ActiveMQ 便打开一个监听端口。ActiveMQ 提供了广泛的连接模式,主要包括 SSL、STOMP、XMPP。ActiveMQ 默认的使用协议为 OpenWire,端口号为 61616。

通信方式:ActiveMQ 有两种通信方式,Point-to-Point Model(点对点模式),Publish/Subscribe Model (发布/订阅模式),其中在 Publich/Subscribe 模式下又有持久化订阅和非持久化订阅两种消息处理方式。

消息存储:在实际应用中,重要的消息通常需要持久化到数据库或文件系统中,确保服务器崩溃时,信息不会丢失。

Cluster(集群):最常见到集群方式包括 Network of Brokers 和 Master Slave。

Monitor(监控):ActiveMQ 一般由 JMX 进行监控。

默认配置下的 ActiveMQ 只适合学习而不适用于实际生产环境,ActiveMQ 的性能需要通过配置挖掘,其性能提高包括代码级性能、规则性能、存储性能、网络性能以及多节点协同方法(集群方案),所以我们优化 ActiveMQ 的中心思路也是这样的:

  1. 优化 ActiveMQ 单个节点性能,包括 NIO 模型选择和存储选择。
  2. 配置 ActiveMQ 集群(ActiveMQ 的高性能和高可用需要通过集群表现出来)。

在生产环境中,ActiveMQ 集群的部署方式主要有下面两种。

  • Master Slave 模式:实现高可用,当主服务器宕机时,备用服务器可以升主,以保证服务的继续。
  • Broker Clusters 模式:实现负载均衡,多个 Broker 之间同步消息,以达到服务器负载的可能。

ActiveMQ 高可用方案

在生产环境中,高可用(High Availability,HA)可谓 “刚需”, ActiveMQ 的高可用性架构基于 Master/Slave 模型。ActiveMQ 总共提供了四种配置方案来配置 HA,其中 Shared Nothing Master/Slave 在 5.8 版本之后不再使用了,并在 ActiveMQ 5.9 版本中引入了基于 Zookeeper 的 Replicated LevelDB Store HA 方案。

关于几种 HA 方案的详细介绍,读者可查看官网说明,在此,我仅做简单介绍。