Java 如何延迟JMS消息发送?
如何延迟JMS消息发送或在不确定的时间内继续 我使用的是Weblogic,正如您所知,在JMS发送之后,接收方将异步处理消息,但是,此时或有时外部资源还没有为接收方做好准备,因此,我希望使用一些检查逻辑来延迟发送或处理消息。我猜例如:我将消息放入挂起队列,然后频繁检查资源可用性,一旦发送或继续消息Java 如何延迟JMS消息发送?,java,jakarta-ee,jms,Java,Jakarta Ee,Jms,如何延迟JMS消息发送或在不确定的时间内继续 我使用的是Weblogic,正如您所知,在JMS发送之后,接收方将异步处理消息,但是,此时或有时外部资源还没有为接收方做好准备,因此,我希望使用一些检查逻辑来延迟发送或处理消息。我猜例如:我将消息放入挂起队列,然后频繁检查资源可用性,一旦发送或继续消息 每个人都知道Weblogic支持这一点吗?或者如何实现它?假设您使用Websphere MQ,我认为它不受支持 JMS 2.0确实支持延迟传递[1]消息,但如果没有更多信息,很难回答 [1] ?如果外
每个人都知道Weblogic支持这一点吗?或者如何实现它?假设您使用Websphere MQ,我认为它不受支持 JMS 2.0确实支持延迟传递[1]消息,但如果没有更多信息,很难回答
[1] ?如果外部资源未准备好,您可以使用接收器块。由于接收者处于“忙碌”状态,因此在队列被阻止时,不会再从队列中拉出消息。您完全可以在JMS中执行此操作,只需使用本地队列来存储消息;当接收器可用时发送到远程队列 选项1(理想、安全) 1) 首先,在WebLogic中创建一个JMS服务器,
LocalJMSServer
2) 确保此资源仅针对本地WebLogic实例
3) 为LocalJMSServer
创建一个队列tempQueue
4) 应用程序总是将消息发送到tempQueue
。因为该队列是本地的,所以消息就放在队列上,并且它们也被持久化,这在服务器崩溃时很好
5) 您需要在WebLogic中使用单独的JMSServer配置来承载remoteQueue
,因为该队列将以远程WebLogic实例为目标
6) 应用程序定期检查远程接收器的可用性:
if( receiverIsAvailable()){
...
}
…当接收器可用时,从tempQueue
中取出消息并发送到remoteQueue
Queue tempQueue = (Queue) ctx.lookup("tempQueue");
QueueSession queueLocalSession =
queueConn.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);
QueueReceiver queueReceiver = queueLocalSession.createReceiver(tempQueue);
TextMessage localMessage = (TextMessage) queueReceiver.receive();
//send to remote queue
Queue remoteQueue = (Queue) ctx.lookup("remoteQueue");
QueueSender queueSender = queueRemoteSession.createSender(remoteQueue);
Message newMessage = queueRemoteSession.createTextMessage(
localMessage.getText());
queueSender.send( newMessage);
//now acknowledge the message since we safely sent to remoteQueue
localMessage.acknowledge();
我喜欢这种方法,因为它完全是事务性的;如果出现任何问题,只要使用持久模式,就不会丢失消息。此外,从tempQueue
提取消息时,必须使用同步接收器(如上所述),不能使用onMessage()
,因为它会立即处理来自本地队列的消息
选项2(更简单、更不安全)
您还可以使用内存队列(非JMS)在本地存储消息内容:
ArrayBlockingQueue queue = new ArrayBlockingQueue<String>();
queue.add(messageContents1);
queue.add(messageContents2);
...
这种方法的问题是存储在队列中的消息驻留在内存中;如果发件人崩溃,您将丢失这些邮件
希望有帮助 通常,为了延迟消息的接收,直到资源准备就绪,不调用connection.start()方法。逻辑如下:
接收方启动并建立连接,并设置所有JMS资源
未调用connection.start()
等待其他资源初始化
使用connection.Start()启动JMs连接
您甚至可以使用此方法暂停消息侦听器接收的消息。这种技术在使用JMS的GUI工具中非常常见。您是否了解了在WebLogic服务器中配置的JMS对象的交付设置的时间
我在weblogic中从未听说过这样的事情。在我看来,您必须自己实现一个等待队列。JMS的目的是将消息放到队列中,以便接收方异步处理它。那么,你能解释一下“接收者必须立即执行操作”是什么意思吗?谢谢你的重播,只是把问题修改得更清楚一点。谢谢,你能告诉我如何暂停要接收的消息吗?可以在消息侦听器线程外调用Connection.start()和Connection.stop()。在程序停止之前调用connection.stop()是很常见的。要暂停在任何时间点接收的消息,可以调用connection.stop()
if( receiverIsAvailable()){
while(!queue.isEmpty()){
Message message = session.createTextMessage();
message.setText(queue.take());
queueSender.send(message);
}
}