在我的JMS应用程序中,我们在生产者上使用临时队列,以便能够接收来自消费者应用程序的回复。
我正面临着与本帖子中提到的完全相同的问题:http://activemq.2283324.n4.nabble.com/jira-Created-AMQ-3336-Temporary-Destination-errors-on-H-A-failover-in-broker-network-with-Failover-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 config XML:amq1.xml
这里有人能调查一下这个问题,并建议我在这个设置中犯了什么错误吗?
更新:
为了进一步阐明我是如何在代码中执行请求-响应的:
发布于 2012-01-27 00:02:03
有一个代理属性org.apache.activemq.broker.BrokerService#cacheTempDestinations应该有助于故障转移: case。在xml配置中将其设置为true,则在客户端断开连接时不会立即删除临时目标。快速故障转移:重新连接将能够再次从临时队列中产生和/或消费。
有一个基于timeBeforePurgeTempDestinations的计时器任务(默认为5秒)来处理缓存删除。
但需要注意的是,我在activemq-core中没有看到任何使用该属性的测试,所以我不能在这一点上给你任何保证。
发布于 2012-01-25 21:38:53
临时队列是在请求-应答场景中请求者(生产者)所连接的代理上创建的。它们是从javax.jms.Session
创建的,因此在该会话断开连接时,无论是由于客户端断开连接还是代理故障/故障转移,这些队列都将永久消失。当您的某个消费者试图回复这些队列时,其他代理都不会理解这是什么意思;因此您会出现异常。
这需要在思维方式上进行架构转变,假设您想要处理故障转移并持久化所有消息。以下是解决问题的一般方法:
queue:response.<client id>
。如果您的客户端数量有限,则客户端id可能是一个标准名称,如果您有大量客户端,则可能是一个UUID。JMSCorrelationID
头中设置的,应该从请求复制到响应消息。这与Apache Camel针对request-response over messaging所采取的方法类似。
要注意的一件事是,当客户端离开时,队列不会消失,因此您应该设置响应消息的生存时间,以便在未使用消息时将其从代理中删除,否则将获得未使用消息的积压。您还需要设置一个dead letter queue strategy to automatically discard expired messages。
https://stackoverflow.com/questions/6432672
复制相似问题