MQ QueueManager断开连接调用永久挂起问题求助
MQ QueueManager断开连接永久挂起问题
使用amqmdnet 9.2.0.6版本时,调用QueueManager的Disconnect()方法出现永久挂起现象:仅能看到断开调用前的日志条目,调用后程序完全无响应。相关代码如下:
if (queueOut != null) { LogMessage("DisconnectMQ: Closing Put Connection"); try { queueOut.Close(); } catch (Exception ex) { string message = "DisconnectMQ: An error occured"; LogException(message, ex); } finally { queueOut = null; } } //Close all MQ QueueManager connections if (queueManagerIn != null) { try { LogMessage("queueManagerIn.Disconnect()"); queueManagerIn.Disconnect(); } catch (Exception ex) { string message = "DisconnectMQ: An error occured"; LogException(message, ex); } finally { queueManagerIn = null; } }
问题原因分析
- 对象关闭顺序错误:未完全关闭所有关联的子对象(如队列、消息消费者/生产者)就直接断开QueueManager,导致资源占用阻塞断开操作
- 无超时设置:
Close()和Disconnect()默认无超时,若底层资源释放异常会导致无限等待 - 未处理的异步操作/事务:存在未完成的异步消息操作或未提交/回滚的事务,导致断开时阻塞
- 版本已知bug:amqmdnet 9.2.0.6存在部分断开连接时的阻塞问题,属于版本缺陷
解决方案
1. 修正对象关闭顺序
遵循先子对象后父对象的关闭顺序:先关闭所有队列、消费者、生产者等子资源,再断开QueueManager。
2. 添加超时设置
为Close()和Disconnect()操作设置超时时间,避免无限挂起:
// 关闭输出队列(带超时) if (queueOut != null) { LogMessage("DisconnectMQ: Closing Put Connection"); try { // 设置30秒超时 queueOut.Close(30000); } catch (Exception ex) { string message = "DisconnectMQ: 关闭输出队列时出错"; LogException(message, ex); } finally { queueOut = null; } } // 若存在输入队列,同样先关闭 if (queueIn != null) { try { queueIn.Close(30000); } catch (Exception ex) { LogException("DisconnectMQ: 关闭输入队列时出错", ex); } finally { queueIn = null; } } // 最后断开QueueManager if (queueManagerIn != null) { try { LogMessage("queueManagerIn.Disconnect()"); queueManagerIn.Disconnect(); } catch (Exception ex) { string message = "DisconnectMQ: 断开QueueManager时出错"; LogException(message, ex); } finally { queueManagerIn = null; } }
3. 清理未完成的操作
- 确保所有异步消息操作已完成
- 检查并提交/回滚所有未完成的事务
4. 升级库版本
将amqmdnet升级到9.3.x或更高稳定版本,修复已知的断开连接阻塞问题
内容的提问来源于stack exchange,提问作者b_patil
相关产品推荐
相关产品推荐

