地址联合类似于连接的代理上的全组播。发送到Broker-A 上的地址的每条消息都会传递到该代理上的每个队列,但也会传递到Broker-B 及其所有附加队列。

地址联合动态链接到上游或下游代理中的其他地址。它会自动在远程地址上为自身创建一个队列,然后消费该队列并将其复制到本地地址,就好像它们直接发布到该地址一样。

上游代理或地址不需要重新配置。只需在地址中添加下游代理所需的权限。下游配置也适用。

federation address
图 1. 地址联合

1. 拓扑模式

1.1. 对称

federation address symetric
图 2. 地址联合 - 对称

如上所示,发布者和消费者连接到每个代理。队列(这些队列的消费者)可以接收由任一发布者发布的消息。

在此设置中,设置max-hops=1非常重要,这样消息只复制一次,避免循环复制。如果max-hops配置不正确,消费者将收到多份相同消息的副本。

1.2. 全网状

federation address complete graph
图 3. 地址联合 - 全网状

此设置与上面的对称设置相同。所有代理都以对称方式相互联合,创建一个全网状。

如上图所示,发布者和消费者连接到每个代理。这些队列上的队列和消费者可以接收由任一发布者发布的消息。

同样,设置max-hops=1非常重要,这样消息只复制一次,避免循环复制。如果max-hops配置不正确,消费者将收到多份相同消息的副本。

1.3. 环形

federation address ring
图 4. 地址联合 - 环形

在代理环中,每个联合地址仅对环中的另一个地址是上游。为了避免循环问题,将max-hops设置为n - 1非常重要,其中n是环中节点的数量。在上面的示例中,该属性设置为 5,以便环中的每个地址都恰好接收一次消息。

虽然此设置在连接方面成本低廉,但它很脆弱。如果单个代理失败,则整个环都会失败。

1.4. 扇出

federation address fan out
图 5. 地址联合 - 扇出

一个主地址(不需要配置)链接到下游联合地址树。该树可以扩展到任意深度,并且可以在无需重新配置现有代理的情况下进一步扩展。

在这种情况下,发布到主地址的消息可以被连接到树中任何代理的任何消费者接收。

1.5. 转发绑定支持

转发绑定支持可以作为地址策略配置的一部分添加。这将允许联合响应转发绑定以创建需求。例如,假设有一个名为test.federation.source的地址,它被包含为联合地址的匹配项,另一个名为test.federation.target的地址未被包含。通常,当在test.federation.target上创建队列时,这不会导致创建联合消费者,因为该地址不是包含的匹配项的一部分。但是,如果我们创建一个转发绑定,使test.federation.source作为源地址,而test.federation.target作为转发地址,那么现在将创建需求。源地址仍然必须是多播,但目标地址可以是多播任播

这方面的一个用例可能是转发,它将 JMS 主题(多播地址)重定向到 JMS 队列(任播地址)。这允许在主题上进行消息负载均衡,以供不支持 JMS 2.0 和共享订阅的旧版消费者使用。

2. 配置地址联合

联合在broker.xml文件中配置。

地址联合示例设置

<federations>
    <federation name="eu-north-1" user="federation_username" password="32a10275cf4ab4e9">
        <upstream name="eu-east-1">
           <static-connectors>
              <connector-ref>eu-east-connector1</connector-ref>
              <connector-ref>eu-east-connector2</connector-ref>
           </static-connectors>
           <policy ref="news-address-federation"/>
        </upstream>
        <upstream name="eu-west-1" >
           <static-connectors>
              <connector-ref>eu-west-connector1</connector-ref>
              <connector-ref>eu-west-connector2</connector-ref>
           </static-connectors>
           <policy ref="news-address-federation"/>
        </upstream>

        <address-policy name="news-address-federation" max-hops="1" auto-delete="true" auto-delete-delay="300000" auto-delete-message-count="-1" transformer-ref="news-transformer">
           <include address-match="queue.bbc.new" />
           <include address-match="queue.usatoday" />
           <include address-match="queue.news.#" />

           <exclude address-match="queue.news.sport.#" />
        </address-policy>

        <transformer name="news-transformer">
           <class-name>org.foo.NewsTransformer</class-name>
           <property key="key1" value="value1"/>
           <property key="key2" value="value2"/>
        </transformer>
    </federation>
</federations>

在上面的设置中,下游代理eu-north-1配置为连接到两个上游代理eu-east-1eu-west-1。用于连接到此示例中两个代理的凭据是共享的。如果每个上游的凭据不同,可以在上游级别更改凭据。

两个上游都配置了相同的地址策略news-address-federation,该策略选择与任何包含条件匹配的地址,并排除以queue.news.sport开头的任何内容。

联合名称在全局范围内必须唯一。

2.1. address-policy 参数

name

所有地址策略在服务器中必须具有唯一的名称。

include

要包含的地址匹配模式。可以设置多个模式。如果没有设置,则匹配所有地址。

exclude

要排除的地址匹配模式。可以设置多个模式。

max-hops

消息可以在联合地址之间执行的最大跳数。有关详细信息,请参阅上面的拓扑模式

auto-delete

对于地址联合,下游会在上游地址上动态创建持久队列。这用于标记上游队列是否应在下游断开连接且延迟和消息计数参数已满足后删除。它在自动化清理中很有用。如果希望在下游断开连接时无论如何将消息排队到下游,则可能希望禁用此功能。

auto-delete-delay

下游代理断开连接后,上游队列可以进行auto-delete操作之前的时间量(以毫秒为单位)。

auto-delete-message-count

在下游代理断开连接后,上游队列中允许进行auto-delete操作的最大消息数。

transformer-ref

可能希望配置的转换器(请参阅转换器配置)的引用名称,以在联合传输时转换消息。

enable-divert-bindings

设置为true将允许监听转发绑定以创建需求。如果存在与流的包含地址匹配的地址的转发绑定,则与转发的地址匹配的任何队列绑定将创建需求。默认值为false

address-policyqueue-policy元素可以在同一个联合中定义,并链接到同一个上游。

2.2. transformer 参数

name

服务器中用于在address-policyqueue-policy中引用转换器的唯一名称。

transformer-class-name

这是实现org.apache.activemq.artemis.core.server.transformer.Transformer接口的用户定义类的名称。

如果指定了,则将在消息传输之前调用转换器的transform()方法。这为您提供了在消息联合之前转换消息的标头或正文的机会。

property

保存可用于配置转换器的键值对。

2.3. 上游参数

标签upstream定义上游代理连接和要使用的策略。

name

上游联合服务器的唯一名称。

user

此可选属性决定在创建到远程服务器的上游连接时要使用的用户名。如果未指定,则将使用共享联合用户和密码(如果已设置)。

password

此可选属性决定在创建到远程服务器的上游连接时要使用的密码。如果未指定,则将使用共享联合用户和密码(如果已设置)。

static-connectors

使用此项或discovery-group-ref将桥连接到目标服务器。

static-connectorsconnector-ref元素的列表,这些元素指向在其他地方定义的connector元素。连接器封装了要使用的传输(TCP、SSL、HTTP 等)以及服务器连接参数(主机、端口等)方面的知识。

有关连接器是什么以及如何配置连接器的更多信息,请参阅配置传输

discovery-group-ref

使用此项或static-connectors将桥连接到目标服务器。

discovery-group-ref元素有一个属性 - discovery-group-name。此属性指向在其他地方定义的discovery-group。有关发现组是什么以及如何配置它们的更多信息,请参阅发现组

ha

可选参数决定此桥是否应该支持高可用性。使用true将连接到集群中的任何可用服务器,并支持故障转移。默认值为false

circuit-breaker-timeout

当发生连接问题时,由于单个连接由许多联合队列和地址消费者共享,为了避免每个消费者都尝试重新连接,并可能导致惊群问题,将尝试第一个消费者。如果失败,断路器将打开,并将相同的异常返回给所有连接。这是断路器可以关闭并重试连接之前的超时时间。以毫秒为单位。

share-connection

如果为同一个代理配置了下游和上游连接,则只要两个流配置都将此标志设置为 true,就会共享相同的连接。默认值为false

check-period

用于检查联合连接是否已停止从另一台服务器接收 ping 的周期(以毫秒为单位)。默认值为30000

connection-ttl

如果联合连接停止从远程代理接收消息,则该连接应保持活动状态的时间。默认值为60000

call-timeout

当通过联合连接发送数据包并且它是阻塞调用时,例如确认,这是它将在抛出异常之前等待回复的时间(以毫秒为单位)。默认值为30000

call-failover-timeout

类似于call-timeout,但在故障转移尝试期间进行调用时使用。默认值为-1(无超时)。

retry-interval

此可选参数决定如果与目标服务器的连接失败,则后续重新连接尝试之间的周期(以毫秒为单位)。默认值为500毫秒。

retry-interval-multiplier

用于在每次重新连接尝试后增加retry-interval,默认值为 1。

max-retry-interval

重试的最大延迟(以毫秒为单位)。默认值为2000

initial-connect-attempts

系统尝试连接到联合中的远程代理的次数。如果达到最大值,则该代理将被视为永久性关闭,系统将不会将消息路由到该代理。默认值为-1(无限次重试)。

reconnect-attempts

系统尝试重新连接到联合中的远程代理的次数。如果达到最大值,则该代理将被视为永久性关闭,系统将停止将消息路由到该代理。默认值为-1(无限次重试)。

3. 配置下游联合

upstream配置类似,也可以配置下游配置。这是通过向downstream代理发送命令来实现的,使其创建回下游代理的upstream连接。这样做的好处是在某些情况下能够在一个代理上配置所有联邦信息,以便于管理,例如中心辐射型拓扑。

除了一个额外的配置标志需要设置外,downstreamupstream的所有配置选项都适用。

upstream-connector-ref

是一个指向其他地方定义的connector元素的元素。此引用用于告诉下游代理使用哪个连接器来创建回下游代理的新上游连接。

连接器封装了有关使用哪种传输(TCP、SSL、HTTP 等)以及服务器连接参数(主机、端口等)的知识。有关连接器是什么以及如何配置它们的更多信息,请参阅配置传输

下游地址联邦设置示例

   <!--Other config Here -->

<connectors>
   <connector name="netty-connector">tcp://127.0.0.1:61616</connector>
   <connector name="eu-west-1-connector">tcp://127.0.0.1:61616</connector>
   <connector name="eu-east-1-connector">tcp://127.0.0.1:61617</connector>
</connectors>

<acceptors>
   <acceptor name="netty-acceptor">tcp://127.0.0.1:61616</acceptor>
</acceptors>

   <!--Other config Here -->

<federations>
   <federation name="eu-north-1" user="federation_username" password="32a10275cf4ab4e9">
      <downstream name="eu-east-1">
          <static-connectors>
             <connector-ref>eu-east-1-connector</connector-ref>
          </static-connectors>
          <policy ref="news-address-federation"/>
          <upstream-connector-ref>netty-connector</upstream-connector-ref>
      </downstream>
      <downstream name="eu-west-1" >
         <static-connectors>
            <connector-ref>eu-west-1-connector</connector-ref>
         </static-connectors>
         <policy ref="news-address-federation"/>
         <upstream-connector-ref>netty-connector</upstream-connector-ref>
      </downstream>

      <address-policy name="news-address-federation" max-hops="1" auto-delete="true" auto-delete-delay="300000" auto-delete-message-count="-1" transformer-ref="news-transformer">
         <include address-match="queue.bbc.new" />
         <include address-match="queue.usatoday" />
         <include address-match="queue.news.#" />

         <exclude address-match="queue.news.sport.#" />
      </address-policy>

      <transformer name="news-transformer">
         <class-name>org.foo.NewsTransformer</class-name>
         <property key="key1" value="value1"/>
         <property key="key2" value="value2"/>
      </transformer>
   </federation>
</federations>