Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.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 如何延迟JMS消息发送?_Java_Jakarta Ee_Jms - Fatal编程技术网

Java 如何延迟JMS消息发送?

Java 如何延迟JMS消息发送?,java,jakarta-ee,jms,Java,Jakarta Ee,Jms,如何延迟JMS消息发送或在不确定的时间内继续 我使用的是Weblogic,正如您所知,在JMS发送之后,接收方将异步处理消息,但是,此时或有时外部资源还没有为接收方做好准备,因此,我希望使用一些检查逻辑来延迟发送或处理消息。我猜例如:我将消息放入挂起队列,然后频繁检查资源可用性,一旦发送或继续消息 每个人都知道Weblogic支持这一点吗?或者如何实现它?假设您使用Websphere MQ,我认为它不受支持 JMS 2.0确实支持延迟传递[1]消息,但如果没有更多信息,很难回答 [1] ?如果外

如何延迟JMS消息发送或在不确定的时间内继续

我使用的是Weblogic,正如您所知,在JMS发送之后,接收方将异步处理消息,但是,此时或有时外部资源还没有为接收方做好准备,因此,我希望使用一些检查逻辑来延迟发送或处理消息。我猜例如:我将消息放入挂起队列,然后频繁检查资源可用性,一旦发送或继续消息


每个人都知道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);
       }
    }