繁体   English   中英

如何延迟JMS消息发送?

[英]How do I delay JMS Message sending?

如何延迟JMS消息发送或进行不确定的时间?

我正在使用Weblogic,如你所知,在JMS发送之后,接收器将异步处理消息,但是,此时或者有时外部资源还没有为接收器做好准备,因此,我想要一些检查逻辑来延迟发送或处理消息。 我想例如:我将消息放入待处理队列然后经常检查资源可用性,一旦发送或继续消息?

大家都知道Weblogic是支持这个还是如何实现它?

你绝对可以在JMS中执行此操作,只需使用本地队列来存储消息; 当接收器可用时发送到远程队列。

选项1(理想,安全)

1)首先,在WebLogic, LocalJMSServer创建JMS服务器。

2)确保仅将此资源仅定位到本地WebLogic实例。

3)创建一个队列, tempQueue ,用于LocalJMSServer

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(); 

我喜欢这种方法,因为它完全是交易性的; 如果出现任何问题,只要您使用PERSISTENT模式,就不会丢失消息。 此外,从tempQueue提取消息时,必须使用同步接收器(如上所述),因为它会立即处理来自本地队列的消息,所以不能使用onMessage()

选项2(更简单,更安全)

您还可以使用内存中队列(而不是JMS)在本地存储消息内容:

ArrayBlockingQueue queue = new ArrayBlockingQueue<String>();
queue.add(messageContents1);
queue.add(messageContents2);
...

您的应用程序检查接收端的资源可用性,如果可用,只需出列并立即发送真实的JMS消息:

if( receiverIsAvailable()){
   while(!queue.isEmpty()){
      Message message = session.createTextMessage();
      message.setText(queue.take());
      queueSender.send(message);
   }
}

这种方法的问题是存储在queue中的消息驻留在内存中; 如果发件人崩溃,你将丢失这些消息。

希望能帮助到你!

通常,为了延迟接收消息,直到资源准备就绪,不会调用connection.start()方法。 这是逻辑:

  1. 接收器启动并建立连接并设置所有JMS资源。
  2. 不调用connection.start()。
  3. 等待其他资源初始化
  4. 使用connection.start()启动JM连接

您甚至可以使用此方法暂停消息侦听器接收的消息。 这种技术在使用JMS的GUI工具中非常常见。

假设您使用的是Websphere MQ,我认为它不受支持。

JMS 2.0确实支持延迟传递[1]消息,但没有更多信息,很难回答。

[1] https://java.net/projects/jms-spec/pages/JMS20FinalRelease#What_s_new_in_JMS_2.0

如果外部资源未准备好,您可以让接收器阻塞。 由于接收器“忙”,在阻塞时不会再从队列中取出消息。

您是否查看了WebLogic服务器中配置的JMS对象的交付时间设置?

Oracle WebLogic文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM