代理也可以主动建立到另一个服务器的连接,而不是等待客户端连接。

代理连接由 broker.xml 配置文件中的 <broker-connections> XML 元素配置。

<broker-connections>
  ...
</broker-connections>

1. AMQP 服务器连接

ActiveMQ Artemis 代理可以使用 AMQP 协议主动建立连接。这意味着代理可以连接到另一个 AMQP 服务器(不一定是 ActiveMQ Artemis),并在该连接上创建元素。

要定义 AMQP 代理连接,请在 broker.xml 配置文件中的 <broker-connections> 元素中添加 <amqp-connection> 元素。例如

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="other-server" retry-interval="100" reconnect-attempts="-1" user="john" password="doe">
    ...
  </amqp-connection>
</broker-connections>
uri

tcp://host:myport[?options] (这是必需的参数)

name

用于管理目的的连接名称

user

用于连接到端点的用户名(这是一个可选参数)

password

用于连接到端点的密码(这是一个可选参数)

retry-interval

发生错误后等待重新尝试连接的时间(毫秒)。默认值为 5000

reconnect-attempts

默认值为 -1,表示无限次

auto-start

代理连接是否应与代理一起自动启动。默认值为 true。如果为 false,则需要调用管理操作来启动它。

用于传输设置的连接 URI 选项(例如启用和配置 TLS)与其他 Artemis 连接器 URI 相同。有关更多信息,请参阅 传输文档。TLS AMQP 代理连接的示例配置可以在代理 示例 中找到,位于 ./examples/features/broker-connection/amqp-sending-overssl
如果在代理连接上禁用了自动启动,则代理连接的启动将仅在 ServerController 上调用管理方法 startBrokerConnection(connectionName) 后才会发生。
目标端点需要对所有配置的操作具有权限。因此,如果正在使用安全管理器,请确保使用具有足够权限的用户执行配置的操作。

2. AMQP 服务器连接操作

以下类型的操作在 AMQP 服务器连接上受支持

  • 镜像

    • 代理使用与另一个代理的 AMQP 连接,并复制邮件并在网络上传送确认。

  • 联合

    • 代理联合允许本地代理为具有本地需求的地址或队列创建远程接收者。反过来,它也可以将联合配置发送到远程代理,使其在此连接上根据地址或队列的远程需求在本地代理上创建接收者。

  • 发送者

    • 接收到的特定队列上的邮件将被传输到另一个端点。

  • 接收者

    • 代理从另一个端点拉取邮件。

  • 对等

    • 代理在知道如何处理它们的另一个端点上创建发送者和接收者。这目前由 Apache Qpid Dispatch 实现。

3. 重新连接和故障转移

可以确定代理连接上的重新连接方式。

这些是 amqp-connection XML 元素上可用的属性

reconnect-attempts

默认值为 -1(无限)。连接失败后将尝试多少次

retry-interval

默认值为 5000,以毫秒为单位,每次重新尝试连接之间的等待时间

还可以通过在 URI 末尾的 # 后附加逗号分隔的列表来指定代理连接上的备用主机。代理连接将继续尝试备用列表,直到其中一个目标可用于连接。例子

<broker-connections>
  <amqp-connection uri="tcp://ServerA:5672#BackupA:5672,BackupB:5672" name="ServerA" reconnect-attempts="-1" retry-interval="5000">
    ...
  </amqp-connection>
</broker-connections>

Broker Connection Failover 图 1. 代理连接 - 重新连接和故障转移。

前面的例子描绘了连接到 ServerA 失败的情况。系统将尝试连接到 serverA、backupA 和 backupB,直到它成功连接到其中一个节点。

4. 镜像

镜像会复制源代理上发生的任何操作到目标代理。

以下事件通过镜像发送

  • 邮件发送

    • 发送到一个代理的邮件将被“复制”到目标代理。

  • 邮件确认

    • 从一个代理中删除邮件的确认将被发送到目标代理。

    • 请注意,如果邮件在目标镜像上等待消费者,则确认将不会成功,并且邮件可能被两个代理都传送。

  • 队列和地址创建。

  • 队列和地址删除。

默认情况下,每个操作都异步发送,不会阻塞任何客户端。但是,如果在镜像配置上设置 sync=true,则客户端将始终等待每个阻塞操作的镜像。

4.1. 镜像配置

<amqp-connection> 元素中添加 <mirror> 元素以配置到目标代理的镜像。

以下可选参数可以使用

message-acknowledgements

指定是否发送邮件确认。默认值为 true

queue-creation

指定是否发送队列或地址创建事件。默认值为 true

queue-removal

指定是否发送队列或地址删除事件。默认值为 true

address-filter

一个可选的逗号分隔的包含和/或排除过滤器条目列表,用于控制在此代理连接上为其创建哪些地址(和相关队列)镜像事件。也就是说,只有与过滤器匹配的地址的事件才会被镜像到目标代理。当地址以在此字段中指定的包含条目开头时,地址将被匹配,除非地址也被另一个条目明确排除。

排除条目以 ! 为前缀,表示以该值为开头的任何地址都不匹配。如果列表中没有指定包含条目,则所有未明确排除的地址都将匹配。如果未指定 address-filter 属性,则所有地址(和相关队列)都将匹配并被镜像。

例子

  • eu 匹配所有以 eu 开头的地址

  • !eu 匹配除以 eu 开头的地址之外的所有地址

  • eu.uk,eu.de 匹配所有以 eu.ukeu.de 开头的地址

  • eu,!eu.uk 匹配所有以 eu 开头的地址,但不包括以 eu.uk 开头的地址

  • 地址排除始终优先于地址包含。

  • 镜像元素上的地址匹配是基于前缀的,不支持通配符匹配。

sync

如果设置为 true,则任何客户端阻塞操作都将被保留,直到镜像确认收到操作。默认值为 false

  • 请注意,断开的节点将保留来自客户端的所有操作。如果设置 sync=true,则必须在执行任何操作之前重新连接镜像。

镜像配置的示例如下所示

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="mirror">
    <mirror/>
  </amqp-connection>
</broker-connections>

4.2. 存储转发队列

镜像事件始终存储在以 $ACTIVEMQ_ARTEMIS_MIRROR_ 为前缀的本地队列中,然后与代理连接的配置名称连接。

因此,在以下配置中,镜像事件将存储在名为 $ACTIVEMQ_ARTEMIS_MIRROR_brokerB 的队列中。

<broker-connection>
  <amqp-connection uri="tcp://brokerB:5672" name="brokerB">
    <mirror/>
  </amqp-connection>
</broker-connection>

然后将这些邮件传输到 brokerB:5672。将创建到 brokerB 的地址 $ACTIVEMQ_ARTEMIS_MIRROR_brokerB 的生产者。如果配置了安全管理器,则必须在代理连接上为用户提供安全角色。

请注意,队列 $ACTIVEMQ_ARTEMIS_MIRROR_brokerB 实际上不会存在于 brokerB 上,因此它不会在管理控制台上可见。目标代理将相应地处理这些邮件作为镜像事件,并在目标代理上执行适当的操作。

4.3. 预先存在的邮件

代理只会镜像从配置镜像的时间点开始到达的邮件。以前存在的邮件不会转发到其他代理。

5. 双镜像(灾难恢复)

ActiveMQ Artemis 支持自动回退镜像。每条发送的邮件和每个确认都会异步复制到镜像代理。

在下面的图表中,将有两个服务器,分别称为 DataCenter1DataCenter2。为了拥有双镜像配置,需要在每个 broker.xml 中添加镜像代理连接

Broker Connection DR 图 2. 代理连接 - 灾难恢复。

DataCenter1 上,应在 broker.xml 中添加以下代码

<broker-connections>
   <amqp-connection uri="tcp://DataCenter2:5672" name="DC2">
      <mirror/>
   </amqp-connection>
</broker-connections>

以下 xml 代码段应添加到 DataCenter2broker.xml

<broker-connections>
   <amqp-connection uri="tcp://DataCenter1:5672" name="DC1">
      <mirror/>
   </amqp-connection>
</broker-connections>

代理连接将把发送和确认复制到另一个代理,无论它们从哪里发出。如果邮件在 DC1(DataCenter1)上发送,这些邮件将自动传输到 DC2(DataCenter2)。在 DC2 上接收到的邮件确认将自动关联回 DC1。

该规则的唯一例外是,如果任何服务器上已经存在具有待处理邮件的消费者,则镜像确认不会阻止邮件被两个消费者使用。

建议不要在两个服务器上都有活动的消费者。

5.1. 例子

代理 示例 中有一个示例,展示了 ./examples/features/broker-connection/disaster-recovery 中的双代理配置(或灾难恢复)。

在上面提供的示例中,两个代理被配置为相互镜像,一个代理中的任何事件都会立即复制到另一个代理。

6. 发送者和接收者

只需创建发送者或接收者代理连接元素,就可以将 ActiveMQ Artemis 代理连接到另一个 AMQP 端点。

对于 sender,代理在队列上创建一个邮件消费者,该队列将邮件发送到另一个 AMQP 端点。

对于 receiver,代理在地址上创建一个邮件生产者,该地址接收来自另一个 AMQP 端点的邮件。

这两个元素都充当邮件桥。但是,处理邮件不需要额外的开销。发送者和接收者就像 ActiveMQ Artemis 中的任何其他消费者或生产者一样。

发送者或接收者可以配置特定队列。可以使用通配符表达式将发送者和接收者匹配到特定地址或地址 。在配置发送者或接收者时,可以设置以下属性

address-match

使用通配符表达式将发送者或接收者匹配到特定地址或地址

queue-name

为特定队列配置发送者或接收者。

6.1. 例子

使用地址表达式

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="other-server">
    <sender address-match="queues.#"/>
    <!-- notice the local queues for remotequeues.# need to be created on this broker -->
    <receiver address-match="remotequeues.#"/>
  </amqp-connection>
</broker-connections>

<addresses>
  <address name="remotequeues.A">
    <anycast>
      <queue name="remoteQueueA"/>
    </anycast>
  </address>
  <address name="queues.B">
    <anycast>
      <queue name="localQueueB"/>
    </anycast>
  </address>
</addresses>

使用队列名称

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="other-server">
    <receiver queue-name="remoteQueueA"/>
    <sender queue-name="localQueueB"/>
  </amqp-connection>
</broker-connections>

<addresses>
   <address name="remotequeues.A">
     <anycast>
       <queue name="remoteQueueA"/>
     </anycast>
   </address>
   <address name="queues.B">
     <anycast>
       <queue name="localQueueB"/>
     </anycast>
   </address>
</addresses>
接收器只能与已存在的本地队列匹配。因此,如果使用接收器,请确保本地预先创建队列。否则,代理无法匹配远程队列和地址。
不要为同一个目标创建发送器和接收器。这会导致发送和接收的无限循环。

7. 对等体

代理可以配置为对等体,它连接到 Apache Qpid Dispatch Router 并指示它代理将充当给定 AMQP 路点地址(在路由器上配置)的存储转发队列。在这种情况下,客户端连接到路由器以使用路点地址发送和接收消息,路由器将这些消息路由到代理上的队列或从代理上的队列路由这些消息。

对等体配置会导致 ActiveMQ Artemis 为代理连接配置中匹配的每个目标创建一个发送器和接收器对,它们带有特殊配置以让 Qpid Dispatch 知道与代理协作。这取代了传统上需要路由器启动的连接和自动链接。

Qpid Dispatch Router 提供了许多高级网络选项,可以与 ActiveMQ Artemis 结合使用。

使用对等体配置时,会存在与存在发送器和接收器时相同的属性。例如,一个配置,其中名称以 queue. 开头的队列充当匹配路由器路点地址的存储,将是

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="router">
    <peer address-match="queues.#"/>
  </amqp-connection>
</broker-connections>

<addresses>
   <address name="queues.A">
     <anycast>
       <queue name="queues.A"/>
     </anycast>
   </address>
   <address name="queues.B">
     <anycast>
       <queue name="queues.B"/>
     </anycast>
   </address>
</addresses>

路由器上必须有一个匹配的地址路点配置,指示它代理附加到的特定路由器地址应被视为路点。例如,类似的基于前缀的路由器地址配置将是

address {
    prefix: queue
    waypoint: yes
}

有关更多信息,请参阅 Apache Qpid Dispatch Router 的“代理消息传递”文档。

不要使用此功能连接到另一个代理,否则发送的任何消息都将立即准备好消费,从而导致发送和接收的无限回声。
无需使用连接器或自动链接来配置路由器以与代理通信。代理的对等体配置取代了路由器路点使用中的这些方面。

8. 地址注意事项

强烈建议 地址名称队列名称 相同。当使用具有其不同名称(如以下示例中)的队列时,发送器和接收器在创建远程端点时将始终使用 地址 名称

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="other-server">
    <sender address-match="queues.#"/>
  </amqp-connection>
</broker-connections>
<addresses>
  <address name="queues.A">
    <anycast>
      <queue name="distinctNameQueue.A"/>
    </anycast>
  </address>
</addresses>

上面的示例将创建一个指向 queues.A 的 AMQP 发送器。

为避免混淆,建议将 地址 名称队列 名称 保持一致。

9. 联邦

代理联邦允许本地代理为具有本地需求的地址或队列创建远程接收器。相反,代理连接可以将联邦配置发送到远程代理,导致它根据远程代理对该相同连接上的地址或队列的需求在本地代理上创建接收器。

<amqp-connection> 元素中添加 <federation> 元素,以将联邦配置到代理实例。<amqp-connection> 包含所有身份验证和重新连接处理的配置。请参阅上面的部分以配置这些值。

代理连接联邦配置由一个或多个策略组成,这些策略定义了地址或队列的本地或远程联邦配置。

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="federation-example">
    <federation>
       <local-address-policy name="example-local-address-policy">
         <include address-match="local-address.#" />
         <exclude address-match="local-address.excluded" />
       </local-address-policy>
       <local-queue-policy name="example-local-queue-policy">
         <include address-match="address" queue-match="local-queue" />
       </local-queue-policy>
       <remote-address-policy name="example-remote-address-policy">
         <include address-match="remote-address" />
       </remote-address-policy>
       <remote-queue-policy name="example-remote-queue-policy">
         <include address-match="#" queue-match="remote-queue" />
         <exclude address-match="excluded.#" queue-match="remote-queue-excluded" />
       </remote-queue-policy>
    </federation>
  </amqp-connection>
</broker-connections>

9.1. 本地和远程地址联邦

本地或远程地址联邦配置本地或远程代理以监视地址上的需求。当存在需求时,它将在相反代理上的匹配地址上创建一个消费者。由于消费者是在相反代理上的地址上创建的,因此提供给代理连接的身份验证凭据必须具有足够的权限才能从(本地地址联邦)或写入相反代理上的匹配地址(远程地址联邦)。

以下显示了一个地址联邦配置示例。本地和远程地址策略具有相同的配置参数,只有策略元素名称不同。

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="federation-example">
    <federation>
       <local-address-policy name="example-local-address-policy"
                             auto-delete="false"
                             auto-delete-delay="1"
                             auto-delete-message-count="12"
                             max-hops="1"
                             enable-divert-bindings="true">
         <include address-match="local-address.#" />
         <exclude address-match="local-address.excluded" />
       </local-address-policy>
    </federation>
  </amqp-connection>
</broker-connections>
name

策略的名称,这些名称在代理连接的联邦策略元素中应该是唯一的。

include

用于匹配包含地址的地址匹配模式,可以设置多个此模式。如果未设置任何模式,则匹配所有地址。

exclude

用于匹配排除地址的地址匹配模式,可以设置多个此模式,或者如果不需要排除,则可以省略。

max-hops

消息可以执行的最大跃点数,以进行联邦。默认值为 0,适用于大多数简单的联邦部署。但是,在某些拓扑中,可能需要更高的值来防止循环。

auto-delete

对于地址联邦,将在代理上创建一个持久队列,从中联邦消息。将此属性设置为 true 以标记队列,以便在启动代理断开连接并满足延迟和消息计数参数后自动删除。如果您希望自动清理动态创建的队列,这是一个有用的选项。默认值为 false,这意味着不会自动删除队列。

auto-delete-delay

启动代理断开连接后,创建的队列可以符合 auto-delete 的时间(以毫秒为单位)。默认值为 0(如果省略选项)。

auto-delete-message-count

启动代理断开连接后,允许在远程队列中存在的消息最大数量,以便队列可以符合自动删除。默认值为 0

enable-divert-bindings

设置为 true 以启用监听需求的转移绑定。如果转移绑定具有与地址策略的包含地址匹配的地址,则任何匹配转移的转发地址的队列绑定都会创建需求。默认值为 false

9.2. 本地和远程队列联邦

本地或远程队列联邦配置本地或远程代理以监视队列上的需求,当存在需求时,它将在相反代理上的匹配队列上创建一个消费者。由于消费者是在相反代理上的队列上创建的,因此提供给代理连接的身份验证凭据必须具有足够的权限才能从(本地队列联邦)或写入相反代理上的匹配队列(远程队列联邦)。

以下显示了一个队列联邦配置示例。本地和远程队列策略具有相同的配置参数,只有策略元素名称不同。

<broker-connections>
  <amqp-connection uri="tcp://HOST:PORT" name="federation-example">
    <federation>
       <local-queue-policy name="example-local-queue-policy">
         <include address-match="#" queue-match="remote-queue" />
         <exclude address-match="excluded.#" queue-match="remote-queue-excluded" />
       </local-queue-policy>
    </federation>
  </amqp-connection>
</broker-connections>
name

策略的名称。这些名称在代理连接的联邦策略元素中应该是唯一的。

include

用于匹配包含队列的队列匹配模式。可以设置多个此模式。如果未设置任何模式,则匹配所有队列。

exclude

用于匹配排除队列的队列匹配模式。可以设置多个此模式,或者如果不需要排除,则可以省略。

priority-adjustment

当创建联邦消费者时,可以使用此值来确保这些联邦消费者比同一队列上的其他本地消费者具有更低的优先级值。默认值为 -1

include-federated

控制在观察队列以获取需求时,是否应计算来自联邦实例的队列上的消费者,默认情况下,此值为 false,并且不会计算联邦消费者。

9.3. 示例

可以在代理 示例./examples/features/broker-connection 目录下找到用于在各种情况下使用联邦功能的许多示例。