Подтвердить что ты не робот

Производительность 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 подключается к IBM MQ 7.0 (проблема также появляется с 6.0) для JMS
  • Вышеупомянутая логика выполняется одним потоком на сервере. Было бы просто сохранить некоторые объекты (QueueConnection, QueueSession, QueueSender) в памяти, так как нет concurrency.

Мои вопросы

  • Какие типы объектов могут использоваться несколькими сообщениями? (конечно, мы будем включать восстановление ошибок, восстановление этих общих объектов)
  • Каковы наилучшие методы повышения производительности?
4b9b3361

Ответ 1

Единственное, что вам нужно создать снова и снова, это сам msg - если вы отправляете в ту же очередь.

Итак, вы можете вспомнить Connection, Session и Sender.

Ответ 2

Вот некоторые важные части jms spec:

раздел 2.8 Многопоточность

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

раздел 4.4.14 Последовательное выполнение клиентского кода

JMS не вызывает одновременное выполнение клиентского кода, если клиент явно не запрашивает его. Один из способов сделать это - определить, что сеанс сериализует всю асинхронную доставку сообщений

Итак, как уже упоминалось, повторное использование как можно больше. Повторно используйте ConnectionFactory, Connection и Destinations для всех потоков. Для каждой темы повторное использование потребителей и производителей.

Если вы повторно используете JMS-подключение, будьте осторожны, что JMS Provider будет мультиплексировать разные сеансы в этих соединениях. Поэтому, даже если безопасно повторно использовать соединения, возможно, быстрее создать соединение для каждого сеанса, который вам нужен.

Ответ 3

Определите, "поделиться" .

Если вы хотите поделиться между разными потоками, это очень опасно. Вы можете безопасно обмениваться объектом QueueConnectionFactory, а также объектом JMS Connection. Вы не должны совместно использовать объекты Session, Sender/Consumer или Message. То, как работает TIBCO EMS, я не уверен в платформе IBM, но я думаю, что это очень похоже.

Если вы можете быть уверены, что ваш метод отправки не вызывается разными потоками, вы можете его инкапсулировать в класс MySender с переменными-членами Connection, Session и Sender. Но будьте осторожны! Правильно закройте ресурсы при выходе. То, что рекомендует Хейко Рупп. Что-то вроде этого:

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, что позволяет повысить производительность (пакетные отправки и т.д.), Но это зависит от платформы. Я не знаю IBM.