Jms使用者在OutOfMemory中运行

时间:2014-01-19 01:37:41

标签: java jms

我们有一个应用程序从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);
        ..........
}

0 个答案:

没有答案