JMS性能

从性能角度理解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 )保留在内存中会很简单,因为不涉及并发性。

我的问题

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

你需要一次又一次地创建的是msg本身 – 如果你要发送到同一个队列。

所以是的,你可以记住Connection,Session和Sender。

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

2.8节multithreading

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

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

除非客户端明确请求,否则JMS不会导致客户端代码的并发执行。 这样做的一种方法是定义会话序列化所有异步消息传递

所以已经提到尽可能多地重用。 重用所有线程的ConnectionFactory,Connection和Destinations。 为每个Thread重用消费者和生产者。

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

定义“分享”

如果你想分享不同的线程,这是非常危险的。 您可以安全地共享 QueueConnectionFactory对象以及JMS Connection对象。 您不得共享Session,Sender / Consumer或Message对象。 这就是TIBCO EMS如何工作的方式我不确定IBM平台,但我想这是非常相同的。

如果您可以确定不同线程不调用 “send”方法,则可以使用Connection,Session和Sender成员变量将其封装到MySender类中。 但要小心! 在退出时正确关闭资源。 这就是Heiko Rupp推荐的内容。 像这样的东西:

 class MySender { private QueueConnection connection = null; private QueueSession session = null; private QueueSender sender = null; public MySender(...) { /* initialize conn/sess/sender */ } public send(String xmlMsg) { /* sender.send(session.createTextMessage(xmlMsg)) */ } public close() { /* close all resources */ } } 

关于表现。 JMS标准没有太大的改进空间。 保持消息小并优化服务器设置。 仅在需要时使用持久目的地等。阅读适用于您的平台的文档。 但在客户端,没有太多空间。 某些平台为JMS提供了额外的function,允许一些额外的性能提升(批量发送等),但这取决于平台。 我不懂IBM。