Apache ActiveMQ Artemis 包含一个功能完备的 JMS 消息桥。

桥接器的功能是从源队列或主题消费消息,并将它们发送到目标队列或主题,通常是在不同的服务器上。

JMS 桥接器并非旨在替代转换和更专业的系统,例如 Camel。JMS 桥接器可能对本章所述的快速传输很有用,但请记住,更复杂的场景需要转换,需要使用更高级的转换系统,这些系统将应用于超越 Apache ActiveMQ Artemis 的用例。

源服务器和目标服务器不必位于同一个集群中,这使得桥接适合可靠地将消息从一个集群发送到另一个集群,例如跨 WAN,以及连接可能不可靠的地方。

桥接器可以作为独立应用程序部署,也可以作为由 Apache ActiveMQ Artemis 引导的嵌入式 Jetty 实例管理的 Web 应用程序部署。源和目标可以位于同一台虚拟机或另一台虚拟机中。

桥接器还可以用于桥接来自其他非 Apache ActiveMQ Artemis JMS 服务器的消息,只要这些服务器符合 JMS 1.1 标准。

不要将 JMS 桥接器与核心桥接器混淆。JMS 桥接器可以用于桥接任何两个符合 JMS 1.1 标准的 JMS 提供程序,并使用 JMS API。A 核心桥接器) 用于桥接任何两个 Apache ActiveMQ Artemis 实例,并使用核心 API。如果可以,始终优先使用核心桥接器而不是 JMS 桥接器。核心桥接器通常比 JMS 桥接器提供更好的性能。此外,核心桥接器可以在不使用 XA 的情况下提供一次且仅一次的交付保证。

桥接器具有内置的故障恢复能力,因此如果源服务器或目标服务器连接丢失(例如由于网络故障),桥接器将尝试重新连接到源服务器和/或目标服务器,直到它们重新联机。重新联机后,它将恢复正常操作。

桥接器可以使用可选的 JMS 选择器进行配置,因此它只消费与该 JMS 选择器匹配的消息

它可以配置为从队列或主题消费。当它从主题消费时,它可以配置为使用非持久订阅或持久订阅进行消费

JMS 桥接器是一个简单的 POJO,因此可以使用大多数框架进行部署,只需实例化org.apache.activemq.artemis.api.jms.bridge.impl.JMSBridgeImpl类并设置适当的参数即可。

1. JMS 桥接参数

主要的 POJO 是JMSBridge。它可以通过传递给其构造函数的参数进行配置。

  • 源连接工厂工厂

    这将注入SourceCFF bean(也在 beans 文件中定义)。此 bean 用于创建ConnectionFactory

  • 目标连接工厂工厂

    这将注入TargetCFF bean(也在 beans 文件中定义)。此 bean 用于创建目标ConnectionFactory

  • 源目标工厂工厂

    这将注入SourceDestinationFactory bean(也在 beans 文件中定义)。此 bean 用于创建Destination

  • 目标目标工厂工厂

    这将注入TargetDestinationFactory bean(也在 beans 文件中定义)。此 bean 用于创建目标Destination

  • 源用户名

    此参数是创建连接的用户名

  • 源密码

    此参数是创建连接的参数

  • 目标用户名

    此参数是创建目标连接的用户名

  • 目标密码

    此参数是创建目标连接的密码

  • 选择器

    这表示用于从源目标消费消息的 JMS 选择器表达式。只有与选择器表达式匹配的消息才会从源目标桥接到目标目标

    选择器表达式必须遵循JMS 选择器语法

  • 故障重试间隔

    这表示在桥接器检测到源服务器或目标服务器已故障后,在尝试重新创建与源服务器或目标服务器的连接之间等待的时间(以毫秒为单位)。

  • 最大重试次数

    这表示在桥接器检测到源服务器或目标服务器已故障后,尝试重新创建与源服务器或目标服务器的连接的次数。桥接器将在尝试此次数后放弃。-1 代表“永远尝试”。

  • 服务质量

    此参数表示所需的服务质量模式

    可能的值是

    • AT_MOST_ONCE

    • DUPLICATES_OK

    • ONCE_AND_ONLY_ONCE

    请参阅服务质量部分以了解这些模式的说明。

  • 最大批次大小

    这表示在将一批消息发送到目标目标之前,从源目标消费的消息的最大数量。其值必须>= 1

  • 最大批次时间

    这表示在将批次发送到目标之前等待的最大毫秒数,即使消费的消息数量尚未达到MaxBatchSize。其值必须为-1 以表示“永远等待”,或>= 1 以指定实际时间

  • 订阅名称

    如果源目标表示一个主题,并且您希望使用持久订阅从该主题消费,则此参数表示持久订阅名称

  • 客户端 ID

    如果源目标表示一个主题,并且您希望使用持久订阅从该主题消费,则此属性表示在创建/查找持久订阅时要使用的 JMS 客户端 ID

  • 在标头中添加消息 ID

    如果为true,则原始消息的消息 ID 将附加在发送到目标的标头中的消息中ACTIVEMQ_BRIDGE_MSG_ID_LIST。如果消息桥接多次,则将附加每个消息 ID。这使得可以使用分布式请求-响应模式

    收到消息时,您可以使用第一个消息 ID 的关联 ID 发送响应,因此当原始发送方收到响应时,它将能够将其关联起来。

  • MBean 服务器

    要使用 JMX 管理 JMS 桥接器,请设置必须在其中注册 JMS 桥接器 MBean 的 MBean 服务器(例如 JVM 平台 MBean 服务器)

  • 对象名称

    如果设置 MBean 服务器,则还需要设置用于注册 JMS 桥接器 MBean 的对象名称(必须是唯一的)

“transactionManager”属性指向 JTA 事务管理器实现,如果您需要使用“ONCE_AND_ONCE_ONLY”服务质量,则应设置该属性。Apache ActiveMQ Artemis 不会随附此类实现,但如果您在应用程序服务器中运行,则可以注入随附的事务管理器。

2. 源连接工厂和目标连接工厂

源连接工厂工厂和目标连接工厂工厂用于创建连接工厂,该连接工厂用于创建源服务器或目标服务器的连接。

上面的配置示例使用 Apache ActiveMQ Artemis 提供的默认实现,该实现使用 JNDI 查找连接工厂。对于其他应用程序服务器或 JMS 提供程序,可能需要提供新的实现。这可以通过实现org.apache.activemq.artemis.jms.bridge.ConnectionFactoryFactory接口来轻松完成。

3. 源目标工厂和目标目标工厂

同样,这些用于创建或查找目标。

在上面的配置示例中,我们使用了 Apache ActiveMQ Artemis 提供的默认项,该项使用 JNDI 查找目标。

可以通过实现org.apache.activemq.artemis.jms.bridge.DestinationFactory接口来提供新的实现。

4. 服务质量

此处更详细地描述了桥接器使用的服务质量模式。

4.1. AT_MOST_ONCE

使用此 QoS 模式,消息将最多从源到达目标一次。消息从源消费并确认,然后发送到目标。因此,如果在将消息从源中删除和它们到达目标之间发生故障,它们可能会丢失。因此,交付将最多发生一次。

此模式适用于持久消息和非持久消息。

4.2. DUPLICATES_OK

使用此 QoS 模式,消息从源消费,然后在成功发送到目标后确认。因此,如果在发送到目标后但在确认之前发生故障,则在系统恢复后它们可能会再次发送。即,目标可能会在故障后收到重复项。

此模式适用于持久消息和非持久消息。

4.3. ONCE_AND_ONLY_ONCE

此 QoS 模式确保消息将从源到达目标一次且仅一次。(有时,此模式被称为“完全一次”。)如果源和目标都在同一个 Apache ActiveMQ Artemis 服务器实例上,则可以通过在同一本地事务中发送和确认消息来实现。如果源和目标在不同的服务器上,则可以通过将发送和消费会话列入 JTA 事务来实现。JTA 事务由 JTA 事务管理器控制,该管理器需要通过 Bridge 上的 settransactionManager 方法进行设置。

此模式仅适用于持久消息。

对于特定应用程序,可能可以使用不使用 ONCE_AND_ONLY_ONCE QoS 级别来提供一次且仅一次语义。这可以通过使用 DUPLICATES_OK 模式,然后在目标处检查重复项并将其丢弃来完成。一些 JMS 服务器提供自动重复消息检测功能,或者可以在应用程序级别通过维护磁盘上已接收消息 ID 的缓存并将已接收消息与它们进行比较来实现。缓存仅在特定时间段内有效,因此这种方法不如使用 ONCE_AND_ONLY_ONCE 那么严密,但根据您的特定应用程序,它可能是一个不错的选择。

4.4. 超时和 JMS 桥接

目标服务器或源服务器在某个时间点可能不可用。如果发生这种情况,则桥接器将在 JMS 桥接器定义中指定的时间内,每Failure Retry Interval毫秒尝试Max Retries次重新连接。

如果您实现了自己的工厂来查找 JMS 资源,那么您将不得不牢记超时问题。

4.5. 示例

请参考 JMS 桥接示例,该示例展示了如何以编程方式实例化和配置 JMS 桥接,以便在两个独立的 Apache ActiveMQ Artemis 代理之间将消息发送到源目标并从目标目标中消费它们。