保持JMS连接/会话/消费者总是打开一个坏习惯吗?
代码草案示例:
// app startup code
ConnectionFactory cf = (ConnectionFactory)jndiContext.lookup(CF_JNDI_NAME);
Connection connection = cf.createConnection(user,pass);
Session session = connection.createSession(true,Session.TRANSACTIONAL);
MessageConsumer consumer = session.createConsumer(new Queue(queueName));
consumer.setMessageListener(new MyListener());
connection.start();
connection.setExceptionListener(new MyExceptionHandler()); // handle connection error
// ... Message are processed on MyListener asynchronously ...
// app shutdown code
consumer.close();
session.close();
connection.close();
Run Code Online (Sandbox Code Playgroud)
有什么建议可以改善这种JMS使用模式吗?
我对JMS连接池和JMS会话池之间感到困惑.
我有一个Java应用程序,它有大约20个线程处理从供应商产品接收的消息.在推送到JMS主题(所有20个线程的相同主题)之前,每个线程都会对消息进行一些处理.
我想确保没有线程等待免费的JMS连接,因为性能至关重要.但是,当我查看JMS连接工厂时,我看不到为JMS连接配置池大小的任何方法.
现在我真的很困惑.是我应该汇集的JMS会议吗?
任何帮助都非常感谢
谢谢乔
1.)从.net客户端,我如何测试客户端是否连接到服务器(即可以发送和接收)是的,我可以在try块内发送消息并捕获随后的异常,但我希望更优雅的解决方案.
2)如何打开,关闭和重新打开连接?在我尝试解决上面的问题1时,我发现如果我打开连接然后调用connection.Close()我无法从连接工厂获得另一个连接(请参阅下面的代码片段).我收到错误消息XMSCC0008
我使用的是非常标准的vanilla MQ配置.以下是我的客户端连接方式:
ISession session = MQAccess.GetSession(MQAccess.Connection);
IDestination destination = session.CreateTopic(SubTopicName);
Consumer = MQAccess.GetConsumer(session, destination);
Consumer.MessageListener = new MessageListener(HandleMQSubEvent);
MQAccess.Connection.Start();
Run Code Online (Sandbox Code Playgroud)
其中MQAccess是一个小实用程序类.
编辑了添加MQAccess代码的问题:
public static class MQAccess
{
public static readonly MQConfigurationSectionHandler ConfigSettings;
public static readonly IConnectionFactory ConnectionFactory;
private static readonly IConnection connection;
public static IConnection Connection
{
get { return connection; }
}
static MQAccess()
{
ConfigSettings = (MQConfigurationSectionHandler)
ConfigurationManager.GetSection("mq-configuration");
XMSFactoryFactory factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
ConnectionFactory = factory.CreateConnectionFactory();
ConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, ConfigSettings.Hostname);
ConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, ConfigSettings.Port);
ConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, ConfigSettings.Channel);
if (ConfigSettings.QueueManager == string.Empty)
{
ConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, …Run Code Online (Sandbox Code Playgroud) 我们将 .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() 似乎是客户端上的廉价操作。