与 ActiveMQ 5 的区别
架构差异
虽然它们的设计目的是完成相同的任务,但在内部的实现方式有所不同。以下是一些您在计划迁移时需要注意的最显著的架构差异。
在 ActiveMQ 中,我们有几种不同的 IO 连接层实现,例如 tcp(同步)和 nio(非阻塞)。在 Artemis 中,IO 层是使用 Netty 实现的,Netty 是一个 nio 框架。这意味着不再需要在不同的实现之间进行选择,因为默认情况下使用的是非阻塞实现。
每个代理的另一个重要部分是消息存储。大多数 ActiveMQ 用户熟悉 KahaDB。它由消息日志组成,用于快速顺序存储消息(以及其他命令包),以及一个索引,用于在需要时检索消息。
Artemis 有自己的消息存储。它只包含追加式消息日志。由于分页方式的不同,不需要消息索引。我们将在稍后详细介绍。在这一点上,重要的是要说明这两个存储库是不可互换的,如果需要数据迁移,必须仔细规划。
我们所说的分页差异是什么?分页是在代理无法将其内存中的所有传入消息都保存下来时发生的。处理这种情况的策略在两个代理之间有所不同。ActiveMQ 有 *游标*,本质上是准备分派给消费者的消息的缓存。它将尝试将所有传入的消息保存在其中。当我们用完可用内存时,消息会添加到存储库中,但缓存会停止。当空间再次可用时,代理将通过从存储库中批量拉取消息来再次填充缓存。因此,我们需要在代理运行时不时地读取日志。为了做到这一点,我们需要维护一个日志索引,以便可以跟踪消息在日志中的位置。
在 Artemis 中,这方面的处理方式有所不同。整个消息日志保存在内存中,消息直接从日志中分派。当我们用完内存时,消息会在 *生产者端*(在它们到达代理之前)进行分页。它们以到达的顺序存储在连续的页面文件中。一旦内存释放,消息就会从这些页面文件移动到日志中。使用这种分页方式,消息只会在代理启动时从文件日志中读取,以重建内存中的日志版本。在这种情况下,日志只按顺序读取,这意味着不需要在日志中保留消息的索引。
这是 ActiveMQ 5.x 和 Artemis 之间的主要区别之一。尽早了解这一点很重要,因为它会影响许多目标策略设置以及我们配置代理以正确支持这些方案的方式。
解决差异
另一个值得尽早讨论的重要区别是消息寻址和路由方式的差异。ActiveMQ 起源于一个开源 JMS 实现,因此,在其核心,所有 JMS 概念(如队列、主题和持久订阅)都被实现为一等公民。这一切都基于项目中开发的 OpenWire 协议,甚至 KahaDB 消息存储也是以 OpenWire 为中心的。这意味着所有其他支持的协议(如 MQTT 和 AMQP)在内部都会转换为 OpenWire。
Artemis 采用了不同的方法。它只在内部实现队列,所有其他消息传递概念都是通过使用地址将消息路由到适当的队列来实现的。消息传递概念,如发布-订阅(主题)和点对点(队列),是使用地址上不同类型的路由机制来实现的。*多播* 路由用于实现 *发布-订阅* 语义,其中对特定地址的所有订阅者都将获得自己的内部队列,消息将被路由到所有订阅者。*任播* 路由用于实现 *点对点* 语义,其中地址只有一个队列,所有消费者都将订阅它。寻址和路由方案用于所有协议。例如,您可以将 JMS 主题视为一个多播地址。我们将在后面的文章中更详细地介绍这个主题。