我有一个基于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);
}
}
}
答案 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(),因为它不具有性能(显然),也因为它不能与群集中的别名队列或队列一起使用。这就是它;它糟透了。