我们有一个应用程序从Broker接收消息,我们使用Sun MessageQueue。对于单个队列和单个消费者,我们有大约4个消息生成器。我们现在面临的问题是,当Queue持有约70,000时,接收器应用程序崩溃并使用OutOfMemry。我知道问题是因为接收器正在预取所有消息。
我尝试将最大数量的消息设置为较小的数字并激活流量控制,但这并不起作用,因为似乎有一个生产者根本不尊重该消息限制,而其他生产者将完全停止暂停整个应用程序。我知道限制数量的数量只是作为一个建议,但一些生产者会停顿半小时,其他人会继续发布。
是否有可用于限制该队列或整个代理的预取的参数?
编辑: 以下是负责消费者的一段代码:
initializeQueue(){
String queueName = ConfigManager.getString("changeRequest.messageQueue");
String factoryName = ConfigManager.getString("changeRequest.factory");
String initial = ConfigManager.getString("java.naming.factory.initial");
String url = ConfigManager.getString("java.naming.provider.url");
props.put(Context.INITIAL_CONTEXT_FACTORY, initial);
props.put(Context.PROVIDER_URL, url);
InitialContext ctx = new InitialContext(props);
Queue queue = (Queue) ctx.lookup(queueName);
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(factoryName);
ctx.close();
connection = factory.createQueueConnection();
session = connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
receiver = session.createReceiver(queue);
}
------------
run(){
while (true)
{
// receive some messages from the JMS Queue
try
{
session.getTransacted();//access the session to make sure it is still alive
if (timeout == NO_TIMEOUT)
{
log.logTrace("Waiting for messages (No Timeout)", null);
msg = receiver.receive(timeout);//use timeout to give session access above a chance to detect dead connection
}
else
{
log.logTrace("Waiting for messages (" + timeout + ")", null);
msg = receiver.receive(timeout);
}
}
catch (JMSException e)
{
log.logInfo("Error reading Queue ", e);
handleQueueError();
continue;
}
////////////
if (msg == null) // timeout
{
if (oldTimeout != NO_TIMEOUT) {
log.logTrace("Timed Out On Queue", null);
commit = true;
synchronized (this)
{
while ((busy) && (handlersBusy()))
{
try
{
log.logTrace("handlers are busy in run... Waiting...", null);
wait(); // wait until all monitors have called us back.
}
catch (InterruptedException iioe)
{
}
}
}
commit = false;
commit();
timeout = NO_TIMEOUT; // wait for a new message on the Queue. No timeouts
} else {
timeout = oldTimeout;//looping around again
log.logTrace("Timed Out On Queue - looping", null);
}
}
else
{
// someone has told us to shut down. We just wait until we are told to restart..
while (!busy)
{
log.logInfo("ChangeRequest Reader Suspended", null);
synchronized (this)
{
try
{
wait();
}
catch (InterruptedException ie)
{
}
log.logInfo("ChangeRequest Reader Activated", null);
timeout = NO_TIMEOUT; // wait for a new message on the Queue. No timeouts
}
}
change = getChangeRequestFromMessage(msg);
..........
}