gpt4 book ai didi

Java JMS - 消息监听器和 onException

转载 作者:行者123 更新时间:2023-12-01 19:29:08 29 4
gpt4 key购买 nike

我有一个带有主线程和 JMS 线程的应用程序,它们通过 ActiveMQ 5.15.11 相互通信。我可以很好地发送消息,但是我想要一种发回状态或错误的方法。我注意到 MessageListener 允许 onSuccess()onException(ex) 作为两个事件来监听,但是我发现只有 onSuccess() 被调用。

这是我的代码片段。

JMS 线程:

ConnectionFactory factory = super.getConnectionFactory();
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(super.getQueue());
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(m -> {
try {
super.processRmbnConfigMsg(m);
} catch (JMSException | IOException e) {
LOG.error(e.getMessage(), e);

// I can only use RuntimeException.
// Also this exception is what I am expecting to get passed to the onException(..)
// call in the main thread.
throw new RuntimeException(e);
}
});
connection.start();

主线程(向 JMS 发送消息):

sendMessage(xml, new AsyncCallback() {
@Override
public void onException(JMSException e) {
// I am expecting this to be that RuntimeException from the JMS thread.
LOG.error("Error", e);
doSomethingWithException(e);
}

@Override
public void onSuccess() {
LOG.info("Success");
}
});

我期望的是,new RuntimeException(e) 中抛出的异常将以某种方式在 onException(JMSException e) 事件监听器上被拾取,即使 RuntimeException 已被包装。

相反,我总是收到 onSuccess() 事件。我想 onException(..) 事件发生在通信问题期间,但我想要一种将异常发送回调用者的方法。

如何实现收集 JMS 线程中的错误并将其发送回我的调用线程的目标?

最佳答案

您的期望是基于对 JMS 的根本误解。

代理消息传递的基本原则之一是生产者和消费者在逻辑上彼此断开。换句话说...生产者向代理发送一条消息,它不一定关心该消息是否被成功消费,并且它当然不会知道消费它或有任何保证当它被消耗时。同样,消费者不一定知道消息何时或为何发送,或者是谁发送的。这为生产者和消费者之间提供了极大的灵 active 。 JMS 坚持生产者和消费者断开连接的这一原则。

消费者没有直接方式通知生产者其发送的消息的消费出现问题。也就是说,您可以采用所谓的“请求/响应模式”,以便消费者可以向生产者提供某种反馈。您可以找到此模式的解释以及示例代码 here .

此外,您使用的 AsyncCallback 类不是 JMS 的一部分。我相信是org.apache.activemq.AsyncCallback由 ActiveMQ 本身独家提供,它仅提供实际发送操作成功或失败的回调(即不用于消息的消费)。

最后,您应该知道,从 javax.jms.MessageListeneronMessage 方法抛出 RuntimeException 被视为“编程错误” “符合 JMS 规范,应该避免。 JMS 2 规范第 8.7 节指出:

It is possible for a listener to throw a RuntimeException; however, this is considered a client programming error. Well behaved listeners should catch such exceptions and attempt to divert messages causing them to some form of application-specific 'unprocessable message' destination. The result of a listener throwing a RuntimeException depends on the session's acknowledgment mode.

  • AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE - the message will be immediately redelivered. The number of times a JMS provider will redeliver the same message before giving up is provider-dependent. The JMSRedelivered message header field will be set, and the JMSXDeliveryCount message property incremented, for a message redelivered under these circumstances.

  • CLIENT_ACKNOWLEDGE - the next message for the listener is delivered. If a client wishes to have the previous unacknowledged message redelivered, it must manually recover the session.

  • Transacted Session - the next message for the listener is delivered. The client can either commit or roll back the session (in other words, a RuntimeException does not automatically rollback the session).

关于Java JMS - 消息监听器和 onException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60348330/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com