JMS 性能

2022-09-02 09:56:56

我在从性能角度理解JMS时遇到了一些麻烦。我们的应用程序中有这个非常简单的代码:

QueueConnection connection = null;
QueueSession session = null;
QueueSender sender = null;
TextMessage msg = null;

try {
  // The JNDIHelper uses InitialContext to look up things
  QueueConnectionFactory qcf = JNDIHelper.lookupFactory();
  Queue destQueue = JNDIHelper.lookupQueue();

  // These objects are created for every message, which is quite slow
  connection = qcf.createQueueConnection();
  session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  sender = session.createSender(destQueue);

  // This is the actual message
  msg = session.createTextMessage(xmlMsg);
  sender.setTimeToLive(0);
  sender.send(msg);
} 
finally {

  // Close all objects again
  JMSUtilities.safeClose(sender);
  JMSUtilities.safeClose(session);
  JMSUtilities.safeClose(connection);
}

代码是正确的,但上述一些伪影可能可以重用于多条消息。以下是我们的配置:

  • 我们使用 Oracle Weblogic 10.3.3
  • Weblogic 连接到 JMS 的 IBM MQ 7.0(问题也出现在 6.0 中)
  • 上述逻辑由后端服务器上的单个线程执行。将一些对象 (, , ) 保留在内存中会很简单,因为不涉及并发。QueueConnectionQueueSessionQueueSender

我的问题

  • 哪些类型的对象可以在多个消息之间共享?(当然,我们会包括错误恢复,恢复那些共享对象)
  • 提高性能的最佳做法是什么?

答案 1

以下是 jms 规范的一些相关部分:

第 2.8 节 多线程

JMS Object          Supports Concurrent Use
Destination         YES
ConnectionFactory   YES
Connection          YES
Session             NO
MessageProducer     NO
MessageConsumer     NO

第 4.4.14 节 串行执行客户端代码

JMS 不会导致客户端代码的并发执行,除非客户端显式请求它。完成此操作的一种方法是定义会话序列化所有异步消息传递消息

因此,如前所述,尽可能多地重用。重用所有线程的连接网站、连接和目标。对于每个线程重用使用者和生产者。

如果要重用 JMS 连接,请注意 JMS 提供程序将在该连接上多路复用不同的会话。因此,即使重用连接是安全的,为所需的每个会话创建连接也可能更快。


答案 2

您唯一需要一次又一次地创建的内容是它本身 - 如果您要发送到同一队列。msg

所以,是的,您可以记住连接,会话和发件人。


推荐