Websphere 7 MQ应用程序停止拾取消息

时间:2012-06-29 16:49:43

标签: java ibm-mq websphere-7

我有一个基于websphere的代码片段,用于从MQ队列中拾取消息并处理它们。大多数情况下代码工作正常,但每隔几天,代码会继续运行,但即使队列中仍有消息,它仍会停止接收消息。为了让这个过程恢复正常,我需要碰撞应用程序,然后一切都开始正常工作。

消息可能非常大(每条消息最多4MB),我在WAS 7上运行

我没有看到任何似乎代表错误的消息或异常。

这是人们评论

的代码
public class BlipMqProcessor {

    protected static final int ONE_SECOND = 1000;
    protected static final int ONE_HOUR = 60 * 60 * ONE_SECOND;
    protected static final int MQ_READ_TIMEOUT = Integer.parseInt(Constants.MQ_READ_TIMEOUT_IN_SECONDS) * ONE_SECOND;

    protected static int previousMqReasonCode;
    protected static long previousMqErrorTime;

    private BlipXmlProcessor xmlProcessor;

    // Member variables for MQ processing
    protected MQQueueManager qMgr;
    protected MQQueue queue;
    protected MQGetMessageOptions gmo;

    /**
     * Constructs a new BlipMqProcessor with the given values.
     */
    public BlipMqProcessor() {
        this(new BlipXmlProcessor());
    }

    /**
     * Constructs a new BlipMqProcessor with the given values.
     * @param xmlProcessor the processor that will be used to create the
     *      staging table entries.
     */
    public BlipMqProcessor(final BlipXmlProcessor xmlProcessor) {
        super();
        this.xmlProcessor = xmlProcessor;
    }

    /**
     * Reads XML messages from the Constants.MQ_ACCESS_QUEUE_NAME
     * 
     * @throws BlipModelException if there are any 
     */
    public void readFromMQ() throws BlipModelException {
        try {
            createNewConnectionToMQ();
            while(true) {
                MQMessage outputMessage = new MQMessage();
                queue.get(outputMessage,gmo);
                String blipModelXml = outputMessage.readLine();
                BlipLogs.logXML("BlipREQ", "0", blipModelXml);
                processMessage(blipModelXml);
                qMgr.commit();
            }
        } catch (final MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                handleMqException(e);
            }
        } catch (final IOException e) {
            throw new BlipModelException("MQ", "Error reading MQ message.", "BlipMqProcessor.readFromMQ", e);
        } finally {
            cleanupMQResources();
        }
    }


    /**
     * Clean up MQ resources.
     */
    private void cleanupMQResources() {
        // Close queue
        if(queue != null) {
           try {
              queue.close();
           }catch(final MQException e) {
               BlipModelLogger.error("MQ", "BlipMqProcessor", "Problem closing queue: " + e);
           }
        }
        // Disconnect queue manager
        if(qMgr != null) {
            try {
                qMgr.disconnect();
            } catch (final MQException e) {
                BlipModelLogger.error("MQ", "BlipMqProcessor", "Problem disconnecting from qMgr: " + e);
            }
        }
    }

    protected void createNewConnectionToMQ() throws MQException {
        try {
            MQEnvironment.hostname = Constants.MQ_HOST;
            MQEnvironment.channel = Constants.MQ_CHANNEL;
            MQEnvironment.port      = Integer.parseInt(Constants.MQ_PORT);
            if(Constants.MQ_SSL_CIPHER_SUITE != null) {
                MQEnvironment.sslCipherSuite = Constants.MQ_SSL_CIPHER_SUITE;
                MQEnvironment.sslPeerName = Constants.MQ_SSL_PEER;
            } else {
                MQEnvironment.sslCipherSuite = "";
                MQEnvironment.sslPeerName = "";
            }

            qMgr = new MQQueueManager(Constants.MQ_QMGR);
            int openOptions = MQC.MQOO_INPUT_AS_Q_DEF;
            queue = qMgr.accessQueue(Constants.MQ_IN_ACCESS_QUEUE, openOptions);
            gmo = new MQGetMessageOptions();
            gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_SYNCPOINT | MQC.MQGMO_FAIL_IF_QUIESCING;
            gmo.waitInterval = MQ_READ_TIMEOUT;
        } finally {
            MQEnvironment.sslCipherSuite = "";
            MQEnvironment.sslPeerName = "";
        }
    }

    protected void handleMqException(final MQException e) {
        long currentTime = System.currentTimeMillis();
        long timeBetweenMqErrors = currentTime - previousMqErrorTime;
        if (previousMqReasonCode != e.reasonCode || timeBetweenMqErrors > ONE_HOUR) {
            previousMqReasonCode = e.reasonCode;
            previousMqErrorTime = currentTime;
            BlipModelLogger.error("MQ", "BlipMqProcessor", "MQException reading from Access Queue: " + e);
        }
    }


}

1 个答案:

答案 0 :(得分:0)

更改readFromMQ方法;

public void readFromMQ() throws BlipModelException {
    try {
        createNewConnectionToMQ();
        while(true) {
          try {
            MQMessage outputMessage = new MQMessage();
            queue.get(outputMessage,gmo);
            String blipModelXml = outputMessage.readLine();
            BlipLogs.logXML("BlipREQ", "0", blipModelXml);
            processMessage(blipModelXml);
            qMgr.commit();
          } catch (MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
              throw e;
            }
          }
        }
    } catch (final MQException e) {
      handleMqException(e);
    } catch (final IOException e) {
        throw new BlipModelException("MQ", "Error reading MQ message.", "BlipMqProcessor.readFromMQ", e);
    } finally {
        cleanupMQResources();
    }
}

将是快速解决方案;但不优雅。这里有足够的重构空间。

发生的事情是你实际上正在获得MQRC_NO_MSG_AVAILABLE,因为有趣的是,没有其他消息可供检索(在某个时间点,而不是你想的时候);当你决定忽略该异常时,你已经退出了while(true)循环。

您不能使用 queue.getCurrentQueueDepth(),因为它不具有性能(显然),也因为它不能与群集中的别名队列或队列一起使用。这就是它;它糟透了。