重用 IBM.WMQ.MQQueue 对象
我们正在使用 IBM 的 WebSphere MQ 的 .NET API。
创建 MQQueueManager 对象显然是一项昂贵的操作,因此我们缓存并重用这些对象的池。
目前,对于每个请求,我们访问所需的队列:
//obtain queueManager from pool
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions);
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions);
并在完成后关闭它们:
requestQ.Close();
responseQ.Close();
这是最佳实践,还是我们还应该池化和重用 MQQueue 对象(除了队列管理器之外)? AccessQueue() 在客户端上似乎是一个廉价的操作。
We are using the .NET API to IBM's WebSphere MQ.
Creating the MQQueueManager object is clearly an expensive operation, and so we cache and reuse a pool of these objects.
Currently, for each request, we access the required queues:
//obtain queueManager from pool
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions);
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions);
and close them once done:
requestQ.Close();
responseQ.Close();
Is this best practice, or should we be also pooling and reusing the MQQueue objects (in addition to the queue manager)? AccessQueue() appears to be a cheap operation on the client.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案取决于您的线程模型和事务性。一般来说,消息传递客户端应该始终使用事务性,即使这只是单阶段提交。原因是结果存在模糊性,否则可能会导致消息重复或丢失。我对此提供了更详细的解释 另一个答案。
问题在于事务是连接范围的。当您提交时,您会对整个连接执行此操作。安全地跨多个线程使用相同的连接将阻止事务的使用,从而使应用程序面临丢失或重复消息的风险。由于队列句柄仅在特定连接的上下文中有效,因此它们继承自线程模型和连接池。
服务提供者应用程序最常见的模型是在输入队列上维护每个线程的连接并动态打开/放置/关闭输出队列。例如,在单个工作单元中...
在这种情况下,连接不会不断重建,输入队列也不会关闭。然而,它确实要求每个线程维护一个专用连接。
The answer depends on your threading model and transactionality. In general, messaging clients should always use transactionality, even if that is only single-phase commit. The reason is that there are ambiguities of outcomes that can cause duplicate or lost messages otherwise. I've provided a much more detailed explanation of this in another answer.
The issue is that transactions are connection-scoped. When you COMMIT you do so for the entire connection. Using the same connection across several threads safely would preclude the use of transactions and thus expose the app to lost or duplicate messages. Since queue handles are only valid in the context of a particular connection, they inherit from your threading model and connection pool.
The most common model for a service provider application is to maintain a connection per-thread on the input queue and dynamically open/put/close the output queue. For example, in a single unit of work...
In this case the connections are not constantly rebuilt, nor is the input queue ever closed. However, it does require each thread to maintain a dedicated connection.