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 使用相关

但技术演进逐渐走向开放独立——不再依赖生产/消费者平台和中间件厂商。新协议定义了自己的目的地模型:

  • AMQP:厂商无关的二进制协议,使用 通用节点
  • MQTT:轻量级二进制协议,面向嵌入式系统和 IoT,使用 主题
  • STOMP:简单文本协议,支持浏览器消息传递,使用 通用目的地

另一大演进是云架构普及带来的转变:从可靠传输单条消息(传统消息),转向“即发即忘”的大数据处理。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,但有 AMQPMQTT 的连接器。

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 对 JMSAMQPMQTTSTOMPKafka 都有良好支持。Spring Boot 更是提供了 ActiveMQArtemisKafka 的嵌入式 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 的事件流能力往往更符合现代需求。


原始标题:Apache ActiveMQ vs. Kafka