1. 概述
在分布式架构中,应用间数据交换是刚需。传统方案是直接通信,但为了实现高可用、分区容错和松耦合,消息队列成了更优解。市面上主流方案有 Apache 基金会旗下的 ActiveMQ 和 Kafka,本文将深入对比这两款产品。
2. 基础概念
2.1 ActiveMQ
ActiveMQ 是传统消息中间件的代表,核心目标是保障应用间数据交换的安全可靠。它专为小数据量场景设计,擅长处理结构化消息和事务性消息。
需要特别注意,除了经典版还有 ActiveMQ Artemis 这个分支。这是 RedHat 在 2015 年将 HornetQ 代码捐给 Apache 后推出的下一代中间件。官网明确表示:
当 Artemis 功能与经典版持平时,将成为 ActiveMQ 的下一个主要版本。
因此对比时需同时考虑两个版本,我们用 ActiveMQ 指代经典版,Artemis 指代新版。
2.2 Kafka
与 ActiveMQ 截然不同,Kafka 是为海量数据处理而生的分布式系统。除了传统消息队列功能,它还支持:
- 网站活动追踪
- 指标监控
- 日志聚合
- 流处理
- 事件溯源
- 提交日志
这些能力在微服务架构盛行的今天显得尤为重要。
2.3 JMS 的角色与消息技术演进
Java 消息服务 (JMS) 是 Java EE 应用中收发消息的标准 API。作为消息系统的早期标准,它至今仍是主流,在 Jakarta EE 中演变为 Jakarta Messaging。核心概念包括:
- Java 原生但厂商无关的 API
- 需通过 JCA 资源适配器 实现厂商特定协议
- 消息目的地模型:
- 队列(点对点模式):保证消息顺序和单次消费,即使有多个消费者
- 主题(发布订阅模式):实现发布-订阅模式,订阅期间所有消费者都能收到消息
- 消息格式:
- Headers:标准化元数据(如优先级、过期时间)
- Properties:非标准化元数据,供消费者处理使用
- Body:消息体——JMS 定义了五种消息类型,但仅 API 使用相关
但技术演进逐渐走向开放独立——不再依赖生产/消费者平台和中间件厂商。新协议定义了自己的目的地模型:
另一大演进是云架构普及带来的转变:从可靠传输单条消息(传统消息),转向“即发即忘”的大数据处理。ActiveMQ 和 Kafka 的对比正是这两种思路的典型代表,Kafka 的替代品还有 NATS。
3. 核心对比
本节从架构和开发角度对比两者的关键特性。
3.1 消息模型、协议与 API
ActiveMQ 完整实现了 JMS 的队列和主题模型,并将 AMQP、MQTT、STOMP 消息映射到这些模型。例如 STOMP 消息会被映射为 JMS BytesMessage 并放入主题。此外它还支持跨语言访问的 OpenWire 协议。
Artemis 则独立定义了自己的消息模型,需要将标准协议映射到该模型:
- 消息发送到 地址(Address),地址包含唯一名称、路由类型 和零个或多个 队列
- 路由类型 决定消息如何从地址路由到绑定队列:
- ANYCAST:消息路由到地址上的单个队列
- MULTICAST:消息路由到地址上的所有队列
Kafka 只定义 主题(Topic),由多个 分区(Partition,至少1个)和可分布在不同 Broker 的 副本(Replica)组成。分区策略是个技术难点:
- 每条消息只进入一个分区
- 仅保证分区内消息有序
- 默认轮询分发消息到各分区
- 使用消息键时,相同键的消息进入同一分区
Kafka 有自己的 API。虽然存在 JMS 资源适配器,但概念不完全兼容。官方不支持 AMQP/MQTT/STOMP,但有 AMQP 和 MQTT 的连接器。
3.2 消息格式与处理
ActiveMQ 支持 JMS 标准消息格式(头部、属性、消息体)。Broker 需维护每条消息的投递状态,导致吞吐量较低。支持消费者同步拉取或 Broker 异步推送。
Kafka 不定义消息格式——完全由生产者决定。不维护单条消息状态,仅记录消费者分区的 偏移量(Offset,最后投递消息的索引)。这不仅速度更快,还能通过重置偏移量重发消息,无需生产者参与。
3.3 Spring 与 CDI 集成
JMS 作为 Java/Jakarta EE 标准,与应用服务器深度集成。ActiveMQ 和 Artemis 连接管理简单,Artemis 甚至支持嵌入式 Broker。Kafka 需通过 JMS 资源适配器 或 Eclipse MicroProfile Reactive 实现托管连接。
Spring 对 JMS、AMQP、MQTT、STOMP 和 Kafka 都有良好支持。Spring Boot 更是提供了 ActiveMQ、Artemis 和 Kafka 的嵌入式 Broker 方案。
4. 适用场景
以下场景建议帮你快速选型。
4.1 ActiveMQ/Artemis 适用场景
- 日消息量较小(万级以下)
- 强调可靠性和事务性
- 需要实时数据转换或 ETL 作业
4.2 Kafka 适用场景
- 高吞吐数据处理
- 实时流处理
- 用户行为追踪
- 日志收集与监控
- 原始消息传递(无需转换)
- 允许消息丢失(非关键业务)
5. 结论
ActiveMQ/Artemis 和 Kafka 各有千秋,选型需结合业务需求。核心差异总结如下:
对比维度 | ActiveMQ 经典版 | ActiveMQ Artemis | Kafka |
---|---|---|---|
核心定位 | 传统消息(可靠、事务) | 分布式事件流 | 分布式事件流 |
点对点 | 队列 | ANYCAST 地址 | - |
发布订阅 | 主题 | MULTICAST 地址 | 主题 |
协议/API | JMS/AMQP/MQTT/STOMP | 协议兼容 | Kafka API + 连接器 |
消息模式 | 推送为主 | 推送为主 | 拉取为主 |
投递责任 | 生产者保证投递 | 生产者保证投递 | 消费者自主消费 |
事务支持 | JMS/XA | 定制事务管理器 | 精确一次 |
扩展性 | Broker 网络 | 集群 | 高扩展(分区+副本) |
消费者增加 | 性能下降 | 性能下降 | 性能不受影响 |
简单粗暴的选型建议:要事务选 ActiveMQ,要吞吐选 Kafka。踩过坑的都知道,在微服务架构中,Kafka 的事件流能力往往更符合现代需求。