位址聯合類似於在連接的代理程式上進行完全多播。發送到 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 參數

名稱

所有位址策略在伺服器中都必須具有唯一的名稱。

包含

要包含位址的位址匹配模式。可以設定多個。如果未設定,則會匹配所有位址。

排除

要排除位址的位址匹配模式。可以設定多個。

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 參數

名稱

伺服器中的唯一名稱,用於參考 address-policyqueue-policy 中的轉換器。

transformer-class-name

這是實作 org.apache.activemq.artemis.core.server.transformer.Transformer 介面的使用者定義類別的名稱。

如果指定,則會在傳輸訊息之前使用該訊息叫用轉換器的 transform() 方法。這讓您有機會在聯合之前轉換訊息的標頭或內文。

property

保存可用於設定轉換器的鍵值組。

2.3. 上游參數

標籤 upstream 定義上游代理程式連線和要使用的策略。

名稱

上游聯合伺服器的唯一名稱。

user

此選用屬性決定在建立與遠端伺服器的上游連線時要使用的使用者名稱。如果未指定,則如果設定了共享聯合使用者和密碼,將會使用它們。

password

此選用屬性決定在建立與遠端伺服器的上游連線時要使用的密碼。如果未指定,則如果設定了共享聯合使用者和密碼,將會使用它們。

static-connectors

使用此參數或 discovery-group-ref 將橋接器連線到目標伺服器。

static-connectors 是指向其他地方定義的 connector 元素的 connector-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 配置類似,可以配置下游配置。其運作方式是向下游代理伺服器發送命令,讓其建立返回到下游代理伺服器的 upstream 連線。這樣做的好處是,在某些情況下能夠在一個代理伺服器上配置所有聯邦設定,以使其更容易,例如星狀拓撲。

所有相同的配置選項都適用於 downstream,就像 upstream 一樣,但需要設定一個額外的配置標誌。

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>