重用 IBM.WMQ.MQQueue 对象

MJ *_*son 5 .net ibm-mq

我们将 .NET API 用于 IBM 的 WebSphere MQ。

创建 MQQueueManager 对象显然是一项昂贵的操作,因此我们缓存并重用这些对象的池。

目前,对于每个请求,我们访问所需的队列:

//obtain queueManager from pool
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions);
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions);
Run Code Online (Sandbox Code Playgroud)

完成后关闭它们:

requestQ.Close();
responseQ.Close();
Run Code Online (Sandbox Code Playgroud)

这是最佳实践,还是我们也应该池化和重用 MQQueue 对象(除了队列管理器)?AccessQueue() 似乎是客户端上的廉价操作。

T.R*_*Rob 0

答案取决于您的线程模型和事务性。一般来说,消息传递客户端应该始终使用事务性,即使这只是单阶段提交。原因是结果存在模糊性,否则可能会导致消息重复或丢失。我在另一个答案中对此提供了更详细的解释。

问题在于事务是连接范围的。当您提交时,您会对整个连接执行此操作。安全地跨多个线程使用相同的连接将阻止事务的使用,从而使应用程序面临丢失或重复消息的风险。由于队列句柄仅在特定连接的上下文中有效,因此它们继承自线程模型和连接池。

服务提供者应用程序最常见的模型是在输入队列上维护每个线程的连接并动态打开/放置/关闭输出队列。例如,在单个工作单元中...

  1. 读取下一条请求消息
  2. 使用回复信息获取目的地
  3. 打开回复队列
  4. 放置响应
  5. 犯罪
  6. 销毁回复目标对象,从而关闭回复队列

在这种情况下,连接不会不断重建,输入队列也不会关闭。然而,它确实要求每个线程维护一个专用连接。