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)
- 上述逻辑由后端服务器上的单个线程执行。 将一些对象(
QueueConnection
,QueueSession
,QueueSender
)保留在内存中会很简单,因为不涉及并发性。
我的问题
- 哪些类型的对象可以在多个消息之间共享? (当然我们会包含错误恢复,恢复这些共享对象)
- 什么是提高绩效的最佳做法?
你需要一次又一次地创建的是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。