此功能提供一種跨遠端代理程式平衡單一佇列負載的方式。

聯邦佇列會連結到其他佇列(稱為上游佇列)。它會從上游佇列擷取訊息,以滿足本地消費者對訊息的需求。上游佇列不需要重新設定,而且它們不必位於相同的代理程式或相同的叢集中。

建立上游連結和聯邦佇列所需的所有設定都在下游代理程式中。

1. 使用案例

這並非您可以使用聯邦佇列完成的所有事項及其優點的完整清單,而只是一些想法。

  • 更高容量

    透過將「邏輯」佇列分散在多個代理程式上。每個代理程式都會宣告一個聯邦佇列,其中所有其他聯邦佇列都是上游。(這些連結會在 n 個佇列上形成完整的雙向圖。)

透過這樣做,邏輯分散式佇列能夠比單一代理程式上的單一佇列具有更高的容量。當存在某種程度的局部性時,效能最佳。

例如,盡可能從與發布訊息相同的代理程式取用訊息,其中聯邦僅需要移動訊息來執行負載平衡。

federated queue symmetric
圖 1. 聯邦佇列對稱
  • 支援多區域或場所

    在多區域設定中,您可能在一個區域或場所中有生產者,而在另一個區域中有消費者。通常,您希望生產者和消費者將其連線保持在該區域的本地,在這種情況下,您可以在生產者和消費者所在的每個區域中部署代理程式,並使用聯邦在區域之間的 WAN 上移動訊息。

federated queue
圖 2. 聯邦佇列
  • 安全企業 LAN 和 DMZ 之間的通訊。

    如果有多個生產者應用程式可能位於 DMZ 中,而多個消費者應用程式位於安全的企業 LAN 中,則允許生產者連線到安全企業 LAN 中的代理程式可能不適合。

    在這種情況下,您可以在生產者發布到的 DMZ 中部署一個代理程式,然後讓企業 LAN 中的代理程式連線到 DMZ 代理程式並聯合佇列,以便訊息可以傳輸。

    這與支援多區域或場所類似。

  • 在兩個叢集之間遷移。可以按任何順序移動消費者和發布者,而且訊息不會重複(如果您執行交換聯邦則會出現這種情況)。相反地,當您的消費者在那裡時,訊息會傳輸到新的叢集。對於在同一個佇列上使用藍/綠或 Canary 移動多個消費者的這種遷移,您可能需要將 priority-adjustment 設定為 0,甚至設定為正值,這樣訊息會主動流向聯邦佇列。

  • 雙重聯邦 - 訊息可能在叢集之間來回跳動。如果您的佇列上的待辦項目超過消費者可用的本地信用額度,則任何較低優先順序的聯邦消費者都會成為分派候選者,並且訊息會聯合。最終,所有訊息都可能會遷移,並且這種情況會在另一個叢集上重複。對連接器 URL 應用速率限制有助於緩解此問題,但當沒有本地消費者時,這可能會對遷移產生不利影響。為了更好地支援此使用案例,可以在引用的連接器 URI 上將 consumerWindowSize 設定為零:tcp://<host>:<port>?consumerWindowSize=0。這將導致聯邦消費者僅在本地佇列有過多容量時才批量提取訊息。這表示聯邦永遠不會耗盡超過其可以處理的訊息,以至於訊息會來回跳動。批次大小來自相關的位址設定 defaultConsumerWindowSize。

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-queue-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-queue-federation"/>
        </upstream>

        <queue-policy name="news-queue-federation" priority-adjustment="-5" include-federated="true" transformer-ref="news-transformer">
           <include queue-match="#" address-match="queue.bbc.new" />
           <include queue-match="#" address-match="queue.usatoday" />
           <include queue-match="#" address-match="queue.news.#" />

           <exclude queue-match="#.local" address-match="#" />
        </queue-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-queue-federation,即選取符合任何包含條件的位址,但會排除任何以 .local 結尾的佇列,僅將它們保留為本地佇列。

聯邦名稱必須是全域唯一的,這一點很重要。

2.1. 優先順序佇列原則參數

名稱

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

包含

要包含位址的位址比對模式。可以設定多個。如果未設定任何位址,則會比對所有位址。

排除

要排除位址的位址比對模式。可以設定多個。

優先順序調整

當消費者附加其優先順序時,會用來建立上游消費者,但預設會調整 -1,以便本地消費者優先進行負載平衡,這使得可以設定此值(如果需要)。

包含聯邦

預設值為 false,我們不會聯合聯邦消費者,這是為了避免在對稱或任何閉環設定中,當沒有附加「真實」消費者時,您可能會遇到訊息無休止地來回流動的問題。

但是,在沒有閉環設定的情況下(例如,鏈中的三個代理程式 (A->B->C),生產者在代理程式 A 上,而消費者在 C 上),這是一種有效的情況,您會希望代理程式 B 將消費者重新聯合到 A 上。

轉換器參考

您可能希望設定的轉換器(請參閱轉換器設定)的參考名稱,以在聯邦傳輸時轉換訊息。

address-policyqueue-policy 元素可以在同一個聯邦中定義,而且它們可以連結到同一個上游。

2.2. 優先順序轉換器參數

名稱

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

轉換器類別名稱

可以指定選用的 transformer-class-name。這是使用者定義類別的名稱,該類別實作 org.apache.activemq.artemis.core.server.transformer.Transformer 介面。

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

屬性

保留可用於設定轉換器的鍵值對。

2.3. 上游參數

標記 upstream 定義上游代理程式連線和要使用的原則。

名稱

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

使用者

這個選用屬性決定建立與遠端伺服器的上游連線時要使用的使用者名稱。如果未指定,則會使用共用的聯邦使用者和密碼(如果已設定)。

密碼

這個選用屬性決定建立與遠端伺服器的上游連線時要使用的密碼。如果未指定,則會使用共用的聯邦使用者和密碼(如果已設定)。

靜態連接器

此屬性或 discovery-group-ref 用於將橋接器連線到目標伺服器。

static-connectors 是指向其他位置定義的 connector 元素的 connector-ref 元素清單。連接器封裝了要使用的傳輸 (TCP、SSL、HTTP 等) 以及伺服器連線參數 (主機、埠等) 的知識。

如需有關連接器是什麼以及如何設定它們的詳細資訊,請參閱設定傳輸

探索群組參考

此屬性或 static-connectors 用於將橋接器連線到目標伺服器。

discovery-group-ref 元素具有一個屬性 - discovery-group-name。此屬性指向其他位置定義的 discovery-group。如需有關探索群組是什麼以及如何設定它們的詳細資訊,請參閱探索群組

高可用性

這個選用參數決定此橋接器是否應支援高可用性。True 表示它會連線到叢集中的任何可用伺服器,並支援容錯移轉。預設值為 false

斷路器逾時

當發生連線問題時,由於多個聯邦佇列和位址消費者共用單一連線,為了避免每個連線嘗試重新連線並可能導致「雷鳴般」的群體問題,將嘗試第一個連線。如果失敗,斷路器將開啟,並將相同的例外狀況傳回所有連線。這是直到可以關閉電路並重試連線的逾時。以毫秒為單位測量。

共用連線

如果為同一個代理程式設定了下游和上游連線,則只要兩個串流組態將此旗標設定為 true,就會共用相同的連線。預設值為 false

檢查週期

用於檢查聯邦連線是否未收到來自另一個伺服器的 Ping 的週期(以毫秒為單位)。預設值為 30000。

連線存留時間

如果聯邦連線停止接收來自遠端代理程式的訊息,則該連線應保持存活的時間長度。預設值為 60000。

呼叫逾時

當透過聯邦連線傳送封包且為封鎖呼叫(即針對確認)時,這是它在擲回例外狀況之前等待回覆的時間(以毫秒為單位)。預設值為 30000。

呼叫容錯移轉逾時

call-timeout 類似,但用於在容錯移轉嘗試期間進行呼叫時。預設值為 -1(無逾時)。

重試間隔

此選用參數決定在連線目標伺服器失敗時,後續重新連線嘗試之間的間隔時間,以毫秒為單位。預設值為 500 毫秒。

retry-interval-multiplier

用於在每次重新連線嘗試後增加 retry-interval 的倍數,預設值為 1。

max-retry-interval

重試的最大延遲時間(以毫秒為單位)。預設值為 2000。

initial-connect-attempts

系統將嘗試連線至聯合中的遠端代理的次數。如果達到max-retry,則此代理將被視為永久關閉,並且系統將不會將訊息路由到此代理。預設值為 -1 (無限次重試)。

reconnect-attempts

系統將嘗試重新連線至聯合中的遠端代理的次數。如果達到max-retry,則此代理將被視為永久關閉,並且系統將停止將訊息路由到此代理。預設值為 -1 (無限次重試)。

3. 設定下游聯合

upstream 設定類似,可以設定下游設定。其運作方式是向 downstream 代理發送命令,讓它建立一個回到下游代理的 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>

      <queue-policy name="news-queue-federation" priority-adjustment="-5" include-federated="true" transformer-ref="news-transformer">
         <include queue-match="#" address-match="queue.bbc.new" />
         <include queue-match="#" address-match="queue.usatoday" />
         <include queue-match="#" address-match="queue.news.#" />

         <exclude queue-match="#.local" address-match="#" />
      </queue-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>