Java ActiveMQ—保留已使用的消息,直到它';s确认删除
我有一个Spring启动应用程序正在侦听ActiveMQ队列 有没有一种方法可以告诉ActiveMQ保留已使用的消息,直到收到从我的服务中删除消息的确认Java ActiveMQ—保留已使用的消息,直到它';s确认删除,java,spring-boot,activemq,Java,Spring Boot,Activemq,我有一个Spring启动应用程序正在侦听ActiveMQ队列 有没有一种方法可以告诉ActiveMQ保留已使用的消息,直到收到从我的服务中删除消息的确认 我的场景是,我从队列中读取消息,一旦消息被消耗,我就将其发送到外部队列。如果外部服务无法处理该消息,我将丢失该消息。我可以告诉active mq保留已消费的消息,直到收到要删除的确认。最安全的选择是使用XA事务以原子方式执行消费/发送(假设发送消息的代理支持XA)。我不确定在Spring中这有多容易或难,但我知道在JavaEE容器中这很简单。您
我的场景是,我从队列中读取消息,一旦消息被消耗,我就将其发送到外部队列。如果外部服务无法处理该消息,我将丢失该消息。我可以告诉active mq保留已消费的消息,直到收到要删除的确认。最安全的选择是使用XA事务以原子方式执行消费/发送(假设发送消息的代理支持XA)。我不确定在Spring中这有多容易或难,但我知道在JavaEE容器中这很简单。您可以使用确认单个消息的个人确认模式。以下是相同的代码:
import javax.jms.Connection;
import javax.jms.JMSException;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQMessageConsumer;
import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.command.ActiveMQTextMessage;
public class SimpleConsumer {
public static void main(String[] args) throws JMSException {
Connection conn = null;
try {
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
conn = cf.createConnection("consumer", "consumer");
ActiveMQSession session = (ActiveMQSession) conn.createSession(false,
ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer) session
.createConsumer(session.createQueue("QUEUE"));
conn.start();
ActiveMQTextMessage msg = null;
while ((msg = (ActiveMQTextMessage) consumer.receive()) != null) {
System.out.println("Received message is: " + msg.getText());
// Call your service and ack the message if successfully processed
msg.acknowledge();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
}
}
作者最初的问题是,当已消费的消息被确认但发送的消息失败时,消息“丢失”。此解决方案打开了另一个问题的大门,即消息可以成功发送,但无法确认(例如,由于网络中断),从而导致重新发送和重复发送消息。如果发送消息是幂等的,则这不是问题,但如果是幂等的,则使用者需要能够检测重复项,或者整个过程需要是原子的(例如,使用XA)。