我们有一个应用程序,它使用JMS从IBMWebsphere队列(7.5版)同步读取4MB消息。在某些情况下,我希望在不读取消息的情况下丢弃队列中的消息。我正试图弄清楚是否有一种方法可以在不阅读整个4MB消息的情况下通过程序实现这一点,这需要几秒钟的时间(可能有数百条消息需要丢弃)。在没有discard()方法(或类似方法)的情况下,以下是我尝试过的:
BytesMessage msg = (BytesMessage)queueReceiver.receiveNoWait();
bytesRead = msg.readBytes(msgBytes, 1024); // just read 1024 bytes
queueReceiver.close();
上面的代码并不比从队列中检索整个4MB消息快(通过读取更大的缓冲区)。这让我相信receiveNoWait()调用是在进行readBytes()调用之前将整个消息下载到内部缓冲区中。我能提供的唯一其他信息是,当会话启动时,队列被设置为"自动确认":
queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
如果我将其更改为CLIENT_ACKNOWLEDGE并使用msg.ACKNOWLEDGE()确认消息,会产生预期效果吗?还是我遗漏了什么?
谢谢你的帮助,Doug
没有其他方法,必须使用消息才能将其从队列中删除。
从AUTO_ACKNOWLEDGE更改为CLIENT_ACKNOWLEDGE不会有任何区别,因为确认是告诉消息提供商从队列中删除消息的一种方式。AUTO_ACKNOWLEDGE选项告诉JMS客户端自动向提供程序发送确认以删除消息,而应用程序使用client_ACKNOWLEDGE来明确告诉提供程序删除消息。
你可能会考虑为你不打算消费的消息设置一个到期时间。设置了过期时间的邮件在过期时间结束后将无法送达。读取消息的JMSExpiration属性。
如果再考虑一下,这里可能还有另一种方法;MQ具有PCF消息的概念——简单地说,就是能够将管理命令作为消息发送到队列管理器。
JMS可以发送这些消息——因此,当您知道不需要更多消息时,可以发送CLEAR_QUEUE命令。
这是一种非常广泛的方法——清除整个队列,但这取决于删除消息的标准。
然而,我可以看到选择性地删除消息的用例——也许值得在IBMdeveloperWorks网站上提出"增强请求"RFE?
据我所知,JMS无法读取部分消息。您只能使用C或Java(非JMS)来实现这一点。
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
try
{
/* get the message with only 1 byte of message data */
_inQ.get(getMsg, gmo, 1);
}
catch (MQException e)
{
System.err.println(e.getLocalizedMessage() );
}