Отношения между JMS-соединениями, сессиями и производителями / потребителями - PullRequest
42 голосов
/ 20 января 2011

Я хочу отправить пакет из 20 000 сообщений JMS в одну и ту же очередь.Я делю задачу, используя 10 потоков, поэтому каждый будет обрабатывать 2k сообщений.Мне не нужны транзакции.

Мне было интересно, рекомендуется ли использовать одно соединение, один сеанс и 10 производителей?

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

Каково общее правило принятия решения о создании нового соединения или сеанса, если я всегда подключаюсь к одной и той же очереди?

Спасибо и извините, что спросили много раз.

(Вот похожий вопрос, но он не совсем ответил на то, что я искал. Долгоживущие сессии JMS.Сохраняет ли соединение JMS / сеансы JMS всегда плохую практику? )

Ответы [ 5 ]

28 голосов
/ 20 января 2011

Это нормально, если некоторые сообщения дублируются или утеряны?Когда JMS-клиент подключается к JMS-брокеру по сети, для любого вызова API есть три фазы.

  1. Вызов API, включая любые данные сообщения, передается посреднику по проводам.
  2. Вызов API выполняется брокером.
  3. Код результата и все данные сообщения передаются обратно клиенту.

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

Рассмотрим потребителя.Если на третьем этапе соединение теряется, сообщение удаляется из очереди, но никогда не возвращается клиенту.Но если сеанс будет выполнен, сообщение будет доставлено при повторном подключении приложения.

Вне транзакций существует вероятность потери или дублирования сообщений.Внутри транзакции существует такое же окно неоднозначности, но оно находится на вызове COMMIT, а не на PUT или GET.В транзакционных сеансах можно отправлять или получать сообщение дважды, но не потерять его.

Спецификация JMS распознает это окно двусмысленности и предоставляет следующие рекомендации:

Еслисбой происходит в то время, когда клиент фиксирует свою работу в сеансе и возвращается метод commit, клиент не может определить, была ли транзакция зафиксирована или откатана.Такая же неоднозначность существует, когда происходит сбой между нетранзакционной отправкой сообщения PERSISTENT и возвратом из метода отправки.

Решение этой неоднозначности решает приложение JMS.В некоторых случаях это может привести к тому, что клиент будет создавать функционально дублирующиеся сообщения.

Сообщение, которое доставляется в результате восстановления сеанса, не считается дублирующим сообщением.

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

Любые рекомендации по влиянию на производительность будут зависеть от поставщика, но в целом постоянные сообщения вне точки синхронизации защищеныдиск до возврата вызова API.Но транзакционный вызов может вернуться до того, как постоянное сообщение будет записано на диск , если сообщение сохраняется до того, как COMMIT вернет .Если поставщик оптимизирует на основе этого, то гораздо эффективнее записать несколько сообщений на диск и затем зафиксировать их в пакетном режиме.Это позволяет брокеру оптимизировать операции записи и очистки диска по дисковым блокам, а не по сообщениям.Количество сообщений, помещаемых в транзакцию, уменьшается с размером сообщения и превышает определенный размер сообщения, уменьшается до единицы.

Если ваши 20k сообщений относительно малы (измеряются в k, а не в мб), тогдавы, вероятно, хотите использовать транзакции для каждого потока и настроить интервал фиксации.

9 голосов
/ 20 января 2011

В большинстве сценариев достаточно работать с одним соединением и несколькими сеансами, используя один сеанс на поток. В некоторых средах вы можете повысить производительность, используя несколько соединений:

Некоторые системы обмена сообщениями поддерживают кластерный режим, при котором соединения распределяются между различными узлами. С несколькими подключениями вы можете использовать производительность нескольких узлов в этом сценарии. (что, конечно, помогает, только когда узкое место находится на стороне брокера сообщений).

Лучшим решением было бы использование пула соединений и предоставление администратору некоторых возможностей для настройки поведения в конкретной области.

4 голосов
/ 10 апреля 2014

Из того, что я исследую в этой теме, один сеанс означает один поток. Это основано на спецификациях JMS. Если вы хотите использовать многопоточность (несколько производителей / потребителей), необходимо создать несколько сеансов, для этого достаточно одного соединения.

4 голосов
/ 13 декабря 2013
I was wondering if having one connection, one session, and 10 producers
is the recommended way to go or not? 

Конечно, но отметим здесь, что вы используете только один поток, то есть тот, который вы создали при создании объекта Session.Все 10 производителей связаны с этим объектом сеанса и, следовательно, с одним и тем же потоком.

How about if I had one producer shared by all the threads? Would my messages
be corrupt or would it be sent out synchronized (giving no performance gain)?

Очень плохая идея, я бы сказал.В спецификациях JMS четко сказано, что сессия не должна использоваться более чем одним потоком.Это не потокобезопасно.

What's the general guideline of deciding whether to create a new connection
or session if I'm always connecting to the same queue?

Если ваша система поддерживает многопоточность, вы можете создать несколько сеансов (каждый сеанс соответствует одному потоку) из одного соединения.Каждый сеанс может иметь несколько производителей / потребителей, но все они не должны быть разделены между потоками.

1 голос
/ 20 января 2011

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

На самом деле это зависит от используемой вами реализации JMS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...