Apache Activemq与Kafka
1.概述
在分布式架构中,应用程序通常需要在它们之间交换数据。一方面,这可以通过彼此直接通信来完成。另一方面,为了达到高可用性和分区容错,以及在应用程序之间获得松耦合,消息传递是一个合适的解决方案。
因此,我们可以在多种产品之间进行选择。Apache 基金会提供了 ActiveMQ 和 Kafka,我们将在本文中对它们进行比较。
2. 一般情况
2.1.主动MQ
**Active MQ 是传统的消息代理之一,其目标是确保应用程序之间的数据交换以安全可靠的方式进行。**它处理少量数据,因此专门用于定义良好的消息格式和事务消息传递。
我们必须注意,除了这个“经典”版本之外,还有另一个版本:Active MQ Artemis。这个下一代代理基于 HornetQ,其代码于 2015 年由 RedHat 提供给 Apache 基金会。在Active MQ 网站上 ,据说:
一旦 Artemis 与“经典”代码库达到足够的功能对等水平,它将成为 ActiveMQ 的下一个主要版本。
因此,为了进行比较,我们需要考虑两个版本。我们将使用术语*“Active MQ”和“Artemis”*来区分它们。
2.2. Kafka
与 Active MQ 相比,**Kafka 是一个分布式系统,旨在处理大量数据。**我们可以将其用于传统消息传递以及:
- 网站活动跟踪
- 指标
- 日志聚合
- 流处理
- 事件溯源
- 提交日志
随着使用微服务构建的典型云架构的出现,这些要求变得非常重要。
2.3. JMS 的作用和消息传递的演变
Java 消息服务 (JMS) 是用于在 Java EE 应用程序中发送和接收消息的通用 API。它是消息传递系统早期发展的一部分,今天它仍然是一个标准。在 Jakarta EE 中,它被采用为Jakarta Messaging。因此,了解核心概念可能会有所帮助:
- Java 原生但独立于供应商的 API
- 需要JCA 资源适配器来实现特定于供应商的通信协议
- 消息目标模型:
- 队列( P2P ) 确保消息排序和一次性消息处理,即使在多个消费者的情况下
- 主题(PubSub)作为发布-订阅模式的实现,这意味着多个消费者将在订阅主题期间接收消息
- 消息格式:
- 标头作为经纪人处理的标准化元信息(如优先级或到期日期)
- 消费者可用于消息处理的非标准化元信息的属性
- 包含有效负载的Body – JMS 声明了五种类型的消息,但这仅与使用 API 有关,与此比较无关
**然而,演变朝着一个开放和独立的方向发展——独立于消费者和生产者的平台,独立于消息代理的供应商。**有一些协议定义了自己的目标模型:
- AMQP —— 独立于供应商的消息传递的二进制协议——使用generic nodes
- MQTT —— 嵌入式系统和物联网的轻量级二进制协议——使用topics
- STOMP —— 一个简单的基于文本的协议,甚至允许从浏览器发送消息 – 使用generic destinations
**另一项发展是通过云架构的传播,根据“即发即弃”原则,将以前可靠的单个消息传输(“传统消息传递”)添加到处理大量数据中。**可以说,Active MQ 和 Kafka 的比较是对这两种方法的典型代表的比较。例如,Kafka 的替代品可能是NATS 。
3.比较
在本节中,我们将比较 Active MQ 和 Kafka 在架构和开发方面最有趣的特性。
3.1.消息目标模型、协议和 API
Active MQ 完全实现了Queues和Topics的 JMS 消息目的地模型,并将 AMQP、MQTT 和 STOMP 消息映射到它们。例如,STOMP 消息映射到Topic中的 JMS BytesMessage。此外,它还支持OpenWire ,它允许跨语言访问 Active MQ。
Artemis 独立于标准 API 和协议定义了自己的消息目标模型,并且还需要将它们映射到此模型:
- Messages 被发送到一个Address,它被赋予一个唯一的名称、一个Routing Type和零个或多个Queues。
- Routing Type确定消息如何从地址路由到绑定到该地址的队列。定义了两种类型:
- ANYCAST:消息被路由到地址上的单个队列
- MULTICAST:消息被路由到地址上的每个队列
Kafka 只定义了Topics,它由多个Partition(至少 1 个)和可以放置在不同 broker 上的 Replica组成。找到划分主题的最佳策略是一项挑战。我们必须注意:
- 一条消息被分配到一个分区中。
- 只有一个分区内的消息才能保证排序。
- 默认情况下,后续消息在主题的分区之间循环分发。
- 如果我们使用消息键,那么具有相同键的消息将落在同一个分区中。
Kafka 有自己的API 。虽然也有JMS 的资源适配器 ,但我们应该知道这些概念并不完全兼容。官方不支持 AMQP、MQTT 和 STOMP,但有AMQP 和MQTT 的连接 器。
3.2. 消息格式和处理
Active MQ 支持由标头、属性和正文组成的 JMS 标准消息格式(如上所述)。代理必须维护每条消息的传递状态,从而导致吞吐量降低。由于它受 JMS 支持,消费者可以从目标同步拉取消息,或者消息可以由代理异步推送。
Kafka 没有定义任何消息格式——这完全是生产者的责任。每条消息没有任何传递状态,只有每个消费者和分区的Offset。Offset是最后发送的消息的索引。这不仅更快,而且还允许通过重置偏移量来重新发送消息,而无需询问生产者。
3.3. Spring 和 CDI 集成
JMS 是 Java/Jakarta EE 标准,因此完全集成到 Java/Jakarta EE 应用程序中。因此,与 Active MQ 和 Artemis 的连接很容易由应用程序服务器管理。使用 Artemis,我们甚至可以使用嵌入式代理 。对于 Kafka,托管连接仅在使用Resource Adapter for JMS 或Eclipse MicroProfile Reactive 时可用。
Spring 集成了JMS 以及AMQP 、MQTT 和STOMP 。还支持Kafka 。借助 Spring Boot,我们可以为Active MQ 、Artemis 和Kafka 使用嵌入式代理。
4. Active MQ/Artemis 和 Kafka 用例
以下几点为我们指明了何时最好使用哪种产品。
4.1.Active MQ/Artemis 的用例
- 每天只处理少量消息
- 高水平的可靠性和事务性
- 即时数据转换,ETL 作业
4.2. Kafka的用例
- 处理大量数据
- 实时数据处理
- 应用程序活动跟踪
- 记录和监控
- 无需数据转换的消息传递(有可能,但并不容易)
- 没有传输保证的消息传递(有可能,但不容易)