Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法使ActiveMQ退出队列_Java_Jms_Activemq - Fatal编程技术网

Java 无法使ActiveMQ退出队列

Java 无法使ActiveMQ退出队列,java,jms,activemq,Java,Jms,Activemq,对此可能有一个愚蠢的简单答案,但我正试图使用ActiveMQ在生产者和消费者之间传递消息。我将有许多生产者和消费者,但我希望每个信息只在消费者中传递一次。这似乎意味着我不能使用主题,因为它们会将消息传递给所有正在收听的消费者,并且我只希望一个消费者接收每条消息 我的问题是我能够接收消息,但消息没有排队。因此,如果我重新启动消费者进程,所有消息都将重新处理。似乎相关,但似乎不适用,因为我无法创建持久队列使用者,只能创建持久主题使用者(除非我在API文档中缺少某些内容) 我的代码如下 TopicCo

对此可能有一个愚蠢的简单答案,但我正试图使用ActiveMQ在生产者和消费者之间传递消息。我将有许多生产者和消费者,但我希望每个信息只在消费者中传递一次。这似乎意味着我不能使用主题,因为它们会将消息传递给所有正在收听的消费者,并且我只希望一个消费者接收每条消息

我的问题是我能够接收消息,但消息没有排队。因此,如果我重新启动消费者进程,所有消息都将重新处理。似乎相关,但似乎不适用,因为我无法创建持久队列使用者,只能创建持久主题使用者(除非我在API文档中缺少某些内容)

我的代码如下

TopicConnectionFactory factory = new ActiveMQConnectionFactory(props.getProperty("mq.url"));
Connection conn  = factory.createConnection();
Session session = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue(props.getProperty("mq.source_queue"));
conn.start();
MessageConsumer consumer = session.createConsumer(queue);
后来

Message msg = consumer.receive();
msg.acknowledge();
if (!(msg instanceof TextMessage)) continue;
String msgStr = ((TextMessage)msg).getText();

这是我当前的代码。我已尝试使用Session.AUTO_ACKNOWLEDGE,但没有使用msg.ACKNOWLEDGE()。此代码的任何工作排列似乎都会检索消息,但当我重新启动消费者时,所有消息都会再次被接收,即使它们在重新启动之前已被接收。

您将会话创建为事务会话,因此需要调用,如果要通知代理所有消息现在都已被使用,并且不需要重新传递,请提交session.commit。如果您没有将createSession的第一个参数设置为true,那么Ack模式将得到尊重,否则它将被忽略,这恐怕是JMS API的一个奇怪之处。如果您这样做:

ConnectionFactory factory = new ActiveMQConnectionFactory(props.getProperty("mq.url"));
Connection conn  = factory.createConnection();
Session session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue(props.getProperty("mq.source_queue"));
conn.start();
MessageConsumer consumer = session.createConsumer(queue);
那么这就行了:

Message msg = consumer.receive();
msg.acknowledge();
否则,您需要执行以下操作:

Message msg = consumer.receive();
session.commit(); 

但是请记住,对于单消息事务来说,对客户端来说没有意义,没有事务的ack是更好的选择

将其更改为conn.createSession(false,Session.CLIENT\u确认);工作。谢谢我想我错过了一些简单的事情。