|
|
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день! Нужно сделать синхронный вызов через JMS из EJB Stateless-компонента. Просьба покритиковать решение: 1. Есть MessageDrivenBean, который слушает очередь для возврата сообщений. В нём есть статичная переменная (первое сомнительное место) ConcurrentHashMap, хранящая пары (UUID,листинер). 2. Отправитель создаёт листенер (второе сомнительное место), генерирует UUID, помещает листинер в Map (не сам, конечно, но это к делу не относится). 3. Затем оправляет сообщение в очередь (пометив его UUID'ом) и засыпает до тех пор, пока не отработает листинер (или таймаут). 4. MDB получив сообщение в очереди просматривает Map, находит по UUID'у листинер, вызывает его и удаляет из Map'а. 5. Отправитель просыпается, читает ответ. Что здесь плохо и что можно поправить? Насколько криминальны два указанных места? -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 10:08:06 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Вам надо использовать обыкновенный паттерн Request/Reply messages design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo - указатель на очередь для ответа, то есть поток 1 посылает запрос в очередь и устанваливает этот заголовок потом блокируется на receive() из этой очереди, поток 2 получает сообщение, что-то делает и отвечает в очередь указанную в заголовке, поток 1 разблокируется - и все тип топ http://www.eaipatterns.com/RequestReplyJmsExample.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 10:41:53 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, забыл ник! > Вам надо использовать обыкновенный паттерн Request/Reply messages > design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo > - указатель на очередь для ответа, то есть поток 1 посылает запрос в > очередь и устанваливает этот заголовок потом блокируется на receive() из > этой очереди, поток 2 получает сообщение, что-то делает и отвечает в > очередь указанную в заголовке, поток 1 разблокируется - и все тип топ А оно разве для моего случая подходит? У меня реально отправителей (т.е. сессий бина) может быть много, причём сколько- никто не знает заранее. Т.е. очередь на отправителя не создашь. -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 10:58:40 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
забыл ник, Именно этот подход используется в Camel - причем бесшовно с точки зрения программиста - заголовки сообщений и временные очереди создаются автоматически. Автор, если есть возможность прикрутить верблюда в систему, думаю все будет просто и наглядно (и с минимальным вмешательством в логику). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 10:59:44 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Kostya Ilyinov, Уточнение - гуглите InOutExchange camel ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 11:00:35 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, Kostya Ilyinov! > Именно этот подход используется в Camel - причем бесшовно с точки зрения > программиста - заголовки сообщений и временные очереди создаются > автоматически. А как правильно вешать слушателя на динамически созданную очередь в JavaEE-приложении? По моему опыту, если слушатель вытеснится на диск, то при восстановлении он уже не будет слушать очередь. Да и собственно, ещё, чем плох мой подход? Есть ли в нём проблемы? -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 11:05:57 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samara, Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком? Как насчет рестрикшинов рестрикшинов в частности enterprise beans should not: create or manage threads ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 11:25:04 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, OOsalivan! > Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком? Нет. Один поток- это собственно поток сессион-бина. Я его только торможу через Thread.sleep. Второй поток- это поток Message-бина. > Как насчет рестрикшинов рестрикшинов Это я знаю и соблюдаю. Из сомнительных действий- статичная переменная и самостоятельное создание объекта (листинер). -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 11:41:08 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_SamaraДобрый день, OOsalivan! > Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком? Нет. Один поток- это собственно поток сессион-бина. Я его только торможу через Thread.sleep. Второй поток- это поток Message-бина. > Как насчет рестрикшинов рестрикшинов Это я знаю и соблюдаю. Из сомнительных действий- статичная переменная и самостоятельное создание объекта (листинер). -- Алексей JID: alxt@ya.ru Значит не знаете или не до конца понимаете - рестрикшины которые относятся к стэйтлес бинам так же и относятся к MDB. А вы в MDB пытаетесь управлять потоком Thread.sleep что и вызывает нарушение ограничений ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 12:37:39 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, OOsalivan! > Значит не знаете или не до конца понимаете - рестрикшины которые > относятся к стэйтлес бинам так же и относятся к MDB. А вы в MDB > пытаетесь управлять потоком Thread.sleep что и вызывает нарушение > ограничений Не пытаюсь. MDB выставляет флаг, Stateless его проверяет. Между проверками- слип. Да, это не оптимально. Но как сделать оптимально и правильно- не знаю. Через динамические очереди- так же будет нарушение правил, того и боюсь (динамическое создание слушателей). -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 12:45:07 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samara, >>Это я знаю и соблюдаю. Из сомнительных действий- статичная переменная Статическая переменная тоже не хорошо. Потому что она уникальна только в пределах класлоадера, если контейнер использует мульти класслоадер то соответственно будет куча проблем (в том числе и с вэйкапом ваших потоков), + проблема на кластере. Не зря в спецификации 3.1 сделали сниглтон ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 12:56:11 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_SamaraДобрый день, забыл ник! > Вам надо использовать обыкновенный паттерн Request/Reply messages > design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo > - указатель на очередь для ответа, то есть поток 1 посылает запрос в > очередь и устанваливает этот заголовок потом блокируется на receive() из > этой очереди, поток 2 получает сообщение, что-то делает и отвечает в > очередь указанную в заголовке, поток 1 разблокируется - и все тип топ А оно разве для моего случая подходит? У меня реально отправителей (т.е. сессий бина) может быть много, причём сколько- никто не знает заранее. Т.е. очередь на отправителя не создашь. -- Алексей JID: alxt@ya.ru Ну не зря это паттерн, не важно сколько у вас отправителей - создание очереди - дело малозатратное, тем более можно создавать временные очереди. Я вам советую почитать Java Message Service 2 ed by Mark Richards, все расставляет по полочкам, в том числе там описан этот паттерн и некоторые другие. авторзабыл ник, Именно этот подход используется в Camel - причем бесшовно с точки зрения программиста - заголовки сообщений и временные очереди создаются автоматически. Автор, если есть возможность прикрутить верблюда в систему, думаю все будет просто и наглядно (и с минимальным вмешательством в логику). Camel хорош бесспорно, но я бы не стал его прикручивать ради только одной этой задачи, но если автор почитает про Camel и подумает что он может заюзать его и в других местах - то я скажу вам только +1 :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 13:17:10 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
OOsalivanСтатическая переменная тоже не хорошо. Потому что она уникальна только в пределах класлоадера, если контейнер использует мульти класслоадер то соответственно будет куча проблем (в том числе и с вэйкапом ваших потоков), + проблема на кластере. Не зря в спецификации 3.1 сделали сниглтон Кстати- можно переменную (да и вообще весь код) в синглтон и перенести... забыл никНу не зря это паттерн, не важно сколько у вас отправителей - создание очереди - дело малозатратное, тем более можно создавать временные очереди. Я вам советую почитать Java Message Service 2 ed by Mark Richards, все расставляет по полочкам, в том числе там описан этот паттерн и некоторые другие. Ушёл читать, спасибо! забыл никCamel хорош бесспорно, но я бы не стал его прикручивать ради только одной этой задачи, но если автор почитает про Camel и подумает что он может заюзать его и в других местах - то я скажу вам только +1 :) И это поучу :) -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:24:45 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
забыл никНу не зря это паттерн, не важно сколько у вас отправителей - создание очереди - дело малозатратное, тем более можно создавать временные очереди. Так можно в JavaEE создавать динамически слушателей, или это возможно только в клиентском коде? -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:25:55 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
забыл никGKS_SamaraДобрый день, забыл ник! > Вам надо использовать обыкновенный паттерн Request/Reply messages > design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo > - указатель на очередь для ответа, то есть поток 1 посылает запрос в > очередь и устанваливает этот заголовок потом блокируется на receive() из > этой очереди, поток 2 получает сообщение, что-то делает и отвечает в > очередь указанную в заголовке, поток 1 разблокируется - и все тип топ А оно разве для моего случая подходит? У меня реально отправителей (т.е. сессий бина) может быть много, причём сколько- никто не знает заранее. Т.е. очередь на отправителя не создашь. -- Алексей JID: alxt@ya.ru Ну не зря это паттерн, не важно сколько у вас отправителей - создание очереди - дело малозатратное, тем более можно создавать временные очереди. Я вам советую почитать Java Message Service 2 ed by Mark Richards, все расставляет по полочкам, в том числе там описан этот паттерн и некоторые другие. авторзабыл ник, Именно этот подход используется в Camel - причем бесшовно с точки зрения программиста - заголовки сообщений и временные очереди создаются автоматически. Автор, если есть возможность прикрутить верблюда в систему, думаю все будет просто и наглядно (и с минимальным вмешательством в логику). Camel хорош бесспорно, но я бы не стал его прикручивать ради только одной этой задачи, но если автор почитает про Camel и подумает что он может заюзать его и в других местах - то я скажу вам только +1 :) Вообще в топике проблема встала именно в JMS в рамках EJB. Указанный выше патерн подходит для обычных jms приложений. Подумайте над вопросом как быть с транзакцией в случае: > посылает запрос в > очередь и устанваливает этот заголовок потом блокируется на receive() Потомучто после блокировки на receive() транзакция не закончиться и соответственно получатель никакого месаджа не увидит, а отправитель так и будет висеть на receive() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:27:09 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, OOsalivan! > Подумайте над вопросом как быть с транзакцией в случае: > >> посылает запрос в >> очередь и устанваливает этот заголовок потом блокируется на receive() > > Потомучто после блокировки на receive() транзакция не закончиться и > соответственно получатель никакого месаджа не увидит, а отправитель так > и будет висеть на receive() У меня я не вижу мест, где может быть блокировка. -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:36:20 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samara, Покажите код отправителя + используемый атрибут транзакции ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:43:16 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samara, Если с точки зрения клиента идет синхронный вызов, то встраивание где то посередине асинхронной отправки и приема сообщений выглядит ни к месту. Почему бы просто не заменить MDB на Stateless bean и не мучатся? У JMS есть вариант синхроного вызова, но такие вызовы не могут транзакционными. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 14:56:57 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, OOsalivan! > Покажите код отправителя + используемый атрибут транзакции Транзакция- по-умолчанию. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Слушатель: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:05:48 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samaraзабыл никНу не зря это паттерн, не важно сколько у вас отправителей - создание очереди - дело малозатратное, тем более можно создавать временные очереди. Так можно в JavaEE создавать динамически слушателей, или это возможно только в клиентском коде? -- Алексей JID: alxt@ya.ru Можно, я же вам ссылку приводил, JMS как раз и создавался держа в уме J2EE, так что это было бы нелепо) авторВообще в топике проблема встала именно в JMS в рамках EJB. Указанный выше патерн подходит для обычных jms приложений. Подумайте над вопросом как быть с транзакцией в случае: > посылает запрос в > очередь и устанваливает этот заголовок потом блокируется на receive() Потомучто после блокировки на receive() транзакция не закончиться и соответственно получатель никакого месаджа не увидит, а отправитель так и будет висеть на receive() Смотря какую вы транзакцию подразумеваете, локальную или распределенную и смотря какие требования для приложения. В случае с локальной транзакцией никаких проблем нет - получаем транзакционную сессию, посылаем месседж, делаем коммит, блокируемся на ресив(). В рамках распределенной транзакции - в большинстве случаев, когда нужно воспользоваться паттерном Request/Reply - никакой речи о распределенных транзакциях вообще не идет, ибо это глупо и нужно искать другое решение или в принципе можно ослабить условие транзакционности именно для JMS, например можно приостановить транзакцию и вызвать JMS без транзакции или с локальной, потом восстановить и т.п. И только в случае если ну прям прям необходимо все обернуть в распределенную транзакцию - можно перейти с варианта с JmsReplyTo и временными очередями на JmsCorrelationId и постоянными очередями. Собственно это все хорошо известно, на самом деле это и есть главное ограничение при работе с JmsReplyTo и временными очередями авторAnother limitation of the QueueRequestor is that the QueueSession cannot be transacted, and will not support the CLIENT_ACKNOWLEDGE message acknowledgment mode. These limitations should also be considered before using the QueueRequestor technique. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:09:02 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
vas0GKS_Samara, Если с точки зрения клиента идет синхронный вызов, то встраивание где то посередине асинхронной отправки и приема сообщений выглядит ни к месту. Почему бы просто не заменить MDB на Stateless bean и не мучатся? У JMS есть вариант синхроного вызова, но такие вызовы не могут транзакционными. +1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:16:07 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Добрый день, vas0! > Если с точки зрения клиента идет синхронный вызов, то встраивание где то > посередине асинхронной отправки и приема сообщений выглядит ни к месту. > Почему бы просто не заменить MDB на Stateless bean и не мучатся? Потому что через MDB идёт отсылка сообщения в другое приложение. Оно слушает очередь и выдаёт ответ. Как сделать прямой вызов из EJB я не понимаю :) -- Алексей JID: alxt@ya.ru Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:19:50 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_SamaraДобрый день, vas0! > Если с точки зрения клиента идет синхронный вызов, то встраивание где то > посередине асинхронной отправки и приема сообщений выглядит ни к месту. > Почему бы просто не заменить MDB на Stateless bean и не мучатся? Потому что через MDB идёт отсылка сообщения в другое приложение. Оно слушает очередь и выдаёт ответ. Как сделать прямой вызов из EJB я не понимаю :) -- Алексей JID: alxt@ya.ru Что-то вы не договариваете, вы же выложили код и слушателя и отправителя, и из этого можно сделать вывод, что вы можете править код и там и там, так почему не заменить JMS на Stateless EJB? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:23:38 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
Стремное у вас какое-то решение с этим sleep() - Под нагрузкой резко увеличивется количество необходимых потоков. - Если в эту транзакцию попадёт база данных, то длинные транзакции будут удерживать больше локов в базе, что приведет к падению производительности базы. - На сколько нормально будет работать штатная остановка сервера, если там будут десятки потоков в sleep()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:27:36 |
|
||
|
Синхронный вызов через JMS
|
|||
|---|---|---|---|
|
#18+
GKS_Samara, Код: java 1. - это создание нового потока в ЕЖБ бине, который слушает ответ и устанавливает done.set(true); в случае когда на сообщение пришел ответ? Создавать свои потоках в бизнес методах нельзя. Если у вас транзакшин атрибут по умолчанию, то отправка сообщения >> ... Далее отправка, msgId включается в атрибуты. не закончиться пока вы не выйдите из метода (в общем случае пока стык вызывающих бизнес методов не завершится). И если вы в "... Далее отправка" не берете из контекста транзакцию и не комитите ее принудительно, то в цикле (while (! done.get() && timeOut-- >= 0)) вы всегда будете выходить по таймауту, потому что jms сообщение в "... Далее отправка" так и не отправиться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2012, 15:42:15 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=37772545&tid=2131896]: |
0ms |
get settings: |
11ms |
get forum list: |
21ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
49ms |
get topic data: |
16ms |
get forum data: |
4ms |
get page messages: |
82ms |
get tp. blocked users: |
2ms |
| others: | 322ms |
| total: | 519ms |

| 0 / 0 |
