【问题标题】:IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2017' ('MQRC_HANDLE_NOT_AVAILABLE')IBM MQ 调用失败,compcode '2' ('MQCC_FAILED') 原因 '2017' ('MQRC_HANDLE_NOT_AVAILABLE')
【发布时间】:2020-04-18 21:08:00
【问题描述】:

在将一些数据放入回复队列时,我遇到了错误。我的应用程序流程是我有一个 MQ 侦听器(Spring Boot Container),它一直在侦听 REQ 队列并处理在 REQ 队列上接收到的数据,最后将处理后的数据放在 REPLY 队列中。

在我的情况下,在一定数量的请求和回复流之后在 REP 队列上发送数据时出现问题,我确信当它达到 MAX HANDLE 计数时,此问题开始出现。对于临时修复,现在我正在重新启动我的 MQ 侦听器容器。

有人可以帮助我在哪里检查 MAXHANDS 计数(我假设它是在 MQ 端配置的),有没有办法在问题被重现后检查多少计数?

注意:我正在使用 IBMMQ,并且所有队列基础架构都由 MQ 团队管理。

错误详情:

原因:com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') 原因 '2017' ('MQRC_HANDLE_NOT_AVAILABLE')。

非常感谢您的即时帮助。

public class MessageHandlerImplRCC implements SessionAwareMessageListener {
  @Override public void onMessage(Message message, Session session) {
    TextMessage imbMqReplyMessage = session.createTextMessage();
    imbMqReplyMessage.setJMSMessageID(message.getJMSMessageID());
    imbMqReplyMessage.setJMSCorrelationID(message.getJMSMessageID());
    imbMqReplyMessage.setText(dlmToDemiMappedString);
    MessageProducer messageProducerIBM = session.createProducer(message.getJMSReplyTo());
    messageProducerIBM.send(imbMqReplyMessage);
    message.acknowledge();
  }
}

【问题讨论】:

  • 显示您的代码。您是否使用事务处理会话?如果是这样,你承诺吗?这有过效果吗?
  • 是的。它已经持续工作了一段时间,突然开始出现上述错误(可能是当它达到 MAXHANDLES 时)。如果我重新启动我的侦听器容器(Spring Boot Container),它再次开始正常运行'public class MessageHandlerImplRCC implements SessionAwareMessageListener { @Override public void onMessage(Message message, Session session) { MessageProducer messageProducerIBM = session.createProducer(message.getJMSReplyTo()); messageProducerIBM.send(imbMqReplyMessage); message.acknowledge();'
  • 公共类 MessageHandlerImplRCC 实现 SessionAwareMessageListener { @Override public void onMessage(Message message, Session session) { TextMessage imbMqReplyMessage = session.createTextMessage(); imbMqReplyMessage.setJMSMessageID(message.getJMSMessageID()); imbMqReplyMessage.setJMSCorrelationID(message.getJMSMessageID()); imbMqReplyMessage.setText(dlmToDemiMappedString); MessageProducer messageProducerIBM = session.createProducer(message.getJMSReplyTo()); messageProducerIBM.send(imbMqReplyMessage); message.acknowledge();}}
  • 我已将您的代码添加到问题中 - 如果您将其放在那里而不是在评论中,则更容易阅读。请检查我没有误报。

标签: java ibm-mq


【解决方案1】:

要查看一项任务可以打开多少句柄,请使用以下 MQSC 命令:-

DISPLAY QMGR MAXHANDS

默认情况下这是 256。但是,您应该关闭不再使用的句柄,而不是增加它。

发出以下 MQSC 命令来查找您的连接。

DISPLAY CONN(*) TYPE(CONN) APPLTAG

并在 APPLTAG 字段中查找您的应用程序名称,然后复制出 CONN 值并发出以下 MQSC 命令:

DISPLAY CONN(paste-in-conn-value) TYPE(ALL) 

你会看到你打开的所有队列。如果您认为不需要将它们全部打开,则关闭不需要的,例如使用:-

messageProducerIBM.close();

重新启动侦听器具有将它们全部关闭的效果,这会将您的句柄数量设置回零。

【讨论】:

  • 感谢您分享您的想法。现在在代码中,我在发送确认后关闭生产者连接。下面的示例代码:'messageProducerIBM.send(imbMqReplyMessage); message.acknowledge(); messageProducerIBM.close();'将在测试后确认其行为,因为此问题仅在一定数量的交易后才会出现。
  • 另请注意,在使用 producer.send 方法调用发送消息后,您正在执行 message.acknowledge。确认方法调用对发送的消息没有影响。确认调用必须在消费(也称为接收)消息后使用,并且仅在使用 CLIENT_ACKNOWLEDGE 类型创建会话时使用。
  • @Shashi 你是对的。目前,我不是在收到消息后发送确认。收到消息后,我会处理相同的消息并将消息发送回 REPLY Queue,然后是 ack 调用,最后现在关闭生产者。您是否认为在 REPLY 队列上发送数据后进行 ACK 调用而不是在收到消息后进行 ACK 调用会导致上述问题?在我当前的代码中,我现在在回复队列上发送消息和 ACK 后关闭生产者。仍在等待重现问题。
  • 不,它们无关。正如@Morag Hughson 正确指出的那样,不关闭制片人是问题所在。
  • @Shashi 有没有办法在 JAVA CODE 中检查队列管理器的 MAXHANDS 数量?类似于 MQSC 中的 DISPLAY QMGR MAXHANDS。
猜你喜欢
  • 2018-08-30
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多