如何延迟JMS消息发送或进行不确定时间?
我正在使用Weblogic,如你所知,在JMS发送之后,接收器将异步处理消息,但是,此时或有时外部资源还没有为接收器做好准备,因此,我想要一些检查逻辑延迟发送或处理消息。我想例如:我将消息放入待处理队列然后经常检查资源可用性,一旦发送或继续消息?
大家都知道Weblogic是支持这个还是如何实现它?
答案 0 :(得分:1)
您绝对可以在JMS中执行此操作,只需使用本地队列来存储消息;当接收器可用时发送到远程队列。
1)首先,在WebLogic中创建一个JMS服务器LocalJMSServer
。
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()
。
您还可以使用内存中队列(而不是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
中的消息驻留在内存中;如果发件人崩溃,你将失去这些信息。
希望它有所帮助!
答案 1 :(得分:1)
通常,为了延迟接收消息,直到资源准备就绪,不会调用connection.start()方法。这是逻辑:
您甚至可以使用此方法暂停消息侦听器接收的消息。这种技术在使用JMS的GUI工具中非常常见。
答案 2 :(得分:0)
假设您使用的是Websphere MQ,我认为它不受支持。
JMS 2.0确实支持延迟传递[1]消息,但没有更多信息,很难回答。
[1] https://java.net/projects/jms-spec/pages/JMS20FinalRelease#What_s_new_in_JMS_2.0?
答案 3 :(得分:0)
如果外部资源尚未就绪,您可以让接收器阻止。由于接收器处于“忙碌状态”,因此在阻塞时不会再从队列中取出消息。
答案 4 :(得分:0)
您是否查看了WebLogic服务器中配置的JMS对象的交付时间设置?