2011-01-19 4 views
35

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

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

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

Какова общая рекомендация по выбору нового соединения или сеанса, если я всегда подключаюсь к одной очереди?

Благодарим вас и прошу прощения за то, что вы задали много вопросов сразу.

(Вот подобный вопрос, но это не совсем ответить на то, что я искал. Long lived JMS sessions. Is Keeping JMS connections/JMS sessions allways open a bad pratice?)

ответ

24

OK, если некоторые из сообщений дублированы или потеряны? Когда клиент JMS подключается к брокеру JMS по сети, существует три этапа для любого вызова API.

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

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

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

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

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

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

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

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

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

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

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

1

В теории Connections потокобезопасны но все остальные не являются, так что вы должны создать одну сессию в нить.

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

9

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

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

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

3
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? 

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

4

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

Смежные вопросы