簡體   English   中英

ActiveMQ:如何在使用臨時隊列時處理代理故障轉移

[英]ActiveMQ: How to handle broker failovers while using temporary queues

在我的JMS應用程序上,我們在Producers上使用臨時隊列,以便能夠從Consumer應用程序接收回復。

我在這個主題中提到的完全相同的問題: http//activemq.2283324.n4.nabble.com/jira-Created-AMQ-3336-Temporary-Destination-errors-on-HA-failover-in -broker-網絡與故障轉移-TT-td3551034.html#a3612738

每當我在網絡中重新啟動一個任意代理時,在嘗試將回復發送到臨時隊列時,我在使用者應用程序日志中收到了許多這樣的錯誤:

javax.jms.InvalidDestinationException:
  Cannot publish to a deleted Destination: temp-queue://ID:...

然后我看到加里在那里建議使用的回應

jms.watchTopicAdvisories=false

作為客戶端brokerURL上的url參數。 我使用此附加參數立即更改了客戶端代理URL。 但是現在,當我在網絡中重新啟動我的代理進行此故障轉移測試時,我發現這樣的錯誤:

javax.jms.JMSException: 
  The destination temp-queue:
    //ID:client.host-65070-1308610734958-2:1:1 does not exist.

我使用的是ActiveMQ 5.5版本。 我的客戶端代理URL如下所示:

failover:(tcp://amq-host1:61616,tcp://amq-host2.tred.aol.com:61616,tcp://amq-host3:61616,tcp://amq-host4:61616)?jms.useAsyncSend=true&timeout=5000&jms.watchTopicAdvisories=false

另外,這是我的4個代理之一的activemq配置XML: amq1.xml

有人可以在這里查看這個問題並建議我在這個設置中犯了什么錯誤。

更新:

為了進一步澄清我在代碼中如何進行請求 - 響應:

  1. 我已經使用了每個生產者目的地(即臨時隊列)並在每個消息的回復標題中設置它。
  2. 我已經在JMSCorrelationID標頭中發送了每條消息唯一的相關標識符。
  3. 據我所知,即使Camel和Spring也使用臨時隊列進行請求 - 響應機制。 唯一的區別是Spring JMS實現為每條消息創建和銷毀臨時隊列,而我在生產者的生命周期中創建臨時隊列。 當客戶端(生產者)應用程序關閉時,或者當AMQ代理意識到沒有與此臨時隊列連接的活動生成器時,將銷毀此臨時隊列。
  4. 我已經在生產者端的每條消息上設置了消息到期,這樣消息就不會在隊列中停留太長時間(60秒)。

有一個代理屬性org.apache.activemq.broker.BrokerService #cacheTempDestinations應該有助於故障轉移:case。 在xml配置中將其設置為true,並且在客戶端斷開連接時不會立即刪除臨時目標。 快速故障轉移:重新連接將能夠再次從臨時隊列生成和/或使用。

有一個基於timeBeforePurgeTempDestinations(默認為5秒)的計時器任務,用於處理緩存刪除。

但有一點需要注意,我沒有在activemq-core中看到任何使用該屬性的測試,因此我無法對此提供任何保證。

在請求 - 應答方案中請求者(生產者)連接的代理上創建臨時隊列。 它們是從javax.jms.Session創建的,因此在該會話斷開連接時,由於客戶端斷開連接或代理失敗/故障轉移,這些隊列將永久消失。 當你的一個消費者試圖回復這些隊列時,其他經紀人都不會理解其含義; 因此你的例外。

這需要在思維模式上進行架構轉換,假設您要處理故障轉移並保留所有消息。 以下是您可以解決問題的一般方法:

  1. 您的回復標題應該引用特定於請求者進程的queue:response.<client id>例如queue:response.<client id> 如果您的客戶端數量有限,則客戶端ID可能是標准名稱;如果您擁有大量客戶端,則客戶端ID可能是UUID。
  2. 出站消息應該設置一個相關標識符(只是一個sting,它允許您將請求與響應相關聯 - 請求者可能同時發出多個請求)。 這是在JMSCorrelationID標頭中設置的,應該從請求復制到響應消息。
  3. 請求者需要在該隊列上設置一個偵聽器,該偵聽器將根據該相關ID將消息體返回給請求線程。 有一些需要為此編寫的多線程代碼,因為您需要手動管理諸如相關ID的映射到原始線程(可能通過Futures)。

這與Apache Camel針對消息傳遞的請求 - 響應采用的方法類似。

需要注意的一點是,當客戶端執行時,隊列不會消失,所以你應該設置一個時間來生成響應消息,這樣如果沒有消耗它就會從代理中刪除,否則你會得到積壓的未消耗的消息。 您還需要設置死信隊列策略以自動丟棄過期的消息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM