powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронный вызов через JMS
25 сообщений из 43, страница 1 из 2
Синхронный вызов через JMS
    #37771717
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Нужно сделать синхронный вызов через 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
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771794
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вам надо использовать обыкновенный паттерн Request/Reply messages design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo - указатель на очередь для ответа, то есть поток 1 посылает запрос в очередь и устанваливает этот заголовок потом блокируется на receive() из этой очереди, поток 2 получает сообщение, что-то делает и отвечает в очередь указанную в заголовке, поток 1 разблокируется - и все тип топ

http://www.eaipatterns.com/RequestReplyJmsExample.html
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771822
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, забыл ник!

> Вам надо использовать обыкновенный паттерн Request/Reply messages
> design. Суть в том что в заголовке сообщения нужно указывать JmsReplyTo
> - указатель на очередь для ответа, то есть поток 1 посылает запрос в
> очередь и устанваливает этот заголовок потом блокируется на receive() из
> этой очереди, поток 2 получает сообщение, что-то делает и отвечает в
> очередь указанную в заголовке, поток 1 разблокируется - и все тип топ

А оно разве для моего случая подходит?

У меня реально отправителей (т.е. сессий бина) может быть много, причём
сколько- никто не знает заранее. Т.е. очередь на отправителя не создашь.

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771825
Kostya Ilyinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,

Именно этот подход используется в Camel - причем бесшовно с точки зрения программиста - заголовки сообщений и временные очереди создаются автоматически. Автор, если есть возможность прикрутить верблюда в систему, думаю все будет просто и наглядно (и с минимальным вмешательством в логику).
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771828
Kostya Ilyinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kostya Ilyinov,

Уточнение - гуглите InOutExchange camel
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771834
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, Kostya Ilyinov!

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

А как правильно вешать слушателя на динамически созданную очередь в
JavaEE-приложении? По моему опыту, если слушатель вытеснится на диск, то
при восстановлении он уже не будет слушать очередь.

Да и собственно, ещё, чем плох мой подход? Есть ли в нём проблемы?

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771886
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_Samara,

Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком?
Как насчет рестрикшинов рестрикшинов в частности
enterprise beans should not: create or manage threads
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37771929
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, OOsalivan!
> Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком?

Нет.
Один поток- это собственно поток сессион-бина. Я его только торможу
через Thread.sleep.
Второй поток- это поток Message-бина.

> Как насчет рестрикшинов рестрикшинов

Это я знаю и соблюдаю.
Из сомнительных действий- статичная переменная и самостоятельное
создание объекта (листинер).

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772104
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_SamaraДобрый день, OOsalivan!
> Я правильно понял что вы в стэйтлес бине пытаетесь управлять потоком?

Нет.
Один поток- это собственно поток сессион-бина. Я его только торможу
через Thread.sleep.
Второй поток- это поток Message-бина.

> Как насчет рестрикшинов рестрикшинов

Это я знаю и соблюдаю.
Из сомнительных действий- статичная переменная и самостоятельное
создание объекта (листинер).

--
Алексей
JID: alxt@ya.ru


Значит не знаете или не до конца понимаете - рестрикшины которые относятся к стэйтлес бинам так же и относятся к MDB. А вы в MDB пытаетесь управлять потоком Thread.sleep что и вызывает нарушение ограничений
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772127
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, OOsalivan!

> Значит не знаете или не до конца понимаете - рестрикшины которые
> относятся к стэйтлес бинам так же и относятся к MDB. А вы в MDB
> пытаетесь управлять потоком Thread.sleep что и вызывает нарушение
> ограничений

Не пытаюсь. MDB выставляет флаг, Stateless его проверяет. Между
проверками- слип. Да, это не оптимально. Но как сделать оптимально и
правильно- не знаю.

Через динамические очереди- так же будет нарушение правил, того и боюсь
(динамическое создание слушателей).

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772156
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_Samara,

>>Это я знаю и соблюдаю. Из сомнительных действий- статичная переменная

Статическая переменная тоже не хорошо. Потому что она уникальна только в пределах класлоадера, если контейнер использует мульти класслоадер то соответственно будет куча проблем (в том числе и с вэйкапом ваших потоков), + проблема на кластере. Не зря в спецификации 3.1 сделали сниглтон
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772226
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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 :)
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772399
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772401
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никНу не зря это паттерн, не важно сколько у вас отправителей - создание
очереди - дело малозатратное, тем более можно создавать временные
очереди.


Так можно в JavaEE создавать динамически слушателей, или это возможно
только в клиентском коде?

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772405
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник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()
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772430
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, OOsalivan!

> Подумайте над вопросом как быть с транзакцией в случае:
>
>> посылает запрос в
>> очередь и устанваливает этот заголовок потом блокируется на receive()
>
> Потомучто после блокировки на receive() транзакция не закончиться и
> соответственно получатель никакого месаджа не увидит, а отправитель так
> и будет висеть на receive()

У меня я не вижу мест, где может быть блокировка.

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772449
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_Samara,

Покажите код отправителя + используемый атрибут транзакции
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772491
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_Samara,

Если с точки зрения клиента идет синхронный вызов, то встраивание где то посередине асинхронной отправки и приема сообщений выглядит ни к месту. Почему бы просто не заменить MDB на Stateless bean и не мучатся?

У JMS есть вариант синхроного вызова, но такие вызовы не могут транзакционными.
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772515
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, 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.
  private static final Map<String, AsyncApiListener> listenerCache =
    new ConcurrentHashMap<String, AsyncApiListener>();
.....
  final AtomicBoolean done = new AtomicBoolean(false);
  final AtomicReference<String> nodeReference =
      new AtomicReference<String>();

  String msgId = UUID.randomUUID().toString();
  xml.addProp("msgId", msgId);
  listenerCache.put(msgId,
    new AsyncApiListener() {
      public void onReply(String xml) {
        nodeReference.set(xml);
        done.set(true);
      }
    },
    destQueue, xml)
  );
  ... Далее отправка, msgId включается в атрибуты.
  while (! done.get() && timeOut-- >= 0)
    try{
      Thread.sleep(1000);
    }catch (InterruptedException e){
      return null;
    }
  if (done.get())
    return nodeReference.get();
  else
    return null;



Слушатель:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
  ... msgId получен из сообщения
  AsyncApiListener l = listenerCache.get(msgId);
  if (l != null) {
    l.onReply(xml);
    listenerCache.remove(msgId);
  } else {
    log.error("no listener for ID={}", msgId);
  }



--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772522
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772535
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0GKS_Samara,

Если с точки зрения клиента идет синхронный вызов, то встраивание где то посередине асинхронной отправки и приема сообщений выглядит ни к месту. Почему бы просто не заменить MDB на Stateless bean и не мучатся?

У JMS есть вариант синхроного вызова, но такие вызовы не могут транзакционными.

+1
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772545
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, vas0!

> Если с точки зрения клиента идет синхронный вызов, то встраивание где то
> посередине асинхронной отправки и приема сообщений выглядит ни к месту.
> Почему бы просто не заменить MDB на Stateless bean и не мучатся?

Потому что через MDB идёт отсылка сообщения в другое приложение.
Оно слушает очередь и выдаёт ответ.
Как сделать прямой вызов из EJB я не понимаю :)

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772549
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_SamaraДобрый день, vas0!

> Если с точки зрения клиента идет синхронный вызов, то встраивание где то
> посередине асинхронной отправки и приема сообщений выглядит ни к месту.
> Почему бы просто не заменить MDB на Stateless bean и не мучатся?

Потому что через MDB идёт отсылка сообщения в другое приложение.
Оно слушает очередь и выдаёт ответ.
Как сделать прямой вызов из EJB я не понимаю :)

--
Алексей
JID: alxt@ya.ru


Что-то вы не договариваете, вы же выложили код и слушателя и отправителя, и из этого можно сделать вывод, что вы можете править код и там и там, так почему не заменить JMS на Stateless EJB?
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772558
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стремное у вас какое-то решение с этим sleep()
- Под нагрузкой резко увеличивется количество необходимых потоков.
- Если в эту транзакцию попадёт база данных, то длинные транзакции будут удерживать больше локов в базе, что приведет к падению производительности базы.
- На сколько нормально будет работать штатная остановка сервера, если там будут десятки потоков в sleep()?
...
Рейтинг: 0 / 0
Синхронный вызов через JMS
    #37772589
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_Samara,

Код: java
1.
new AsyncApiListener()

- это создание нового потока в ЕЖБ бине, который слушает ответ и устанавливает done.set(true); в случае когда на сообщение пришел ответ? Создавать свои потоках в бизнес методах нельзя.

Если у вас транзакшин атрибут по умолчанию, то отправка сообщения
>> ... Далее отправка, msgId включается в атрибуты.
не закончиться пока вы не выйдите из метода (в общем случае пока стык вызывающих бизнес методов не завершится). И если вы в "... Далее отправка" не берете из контекста транзакцию и не комитите ее принудительно, то в цикле (while (! done.get() && timeOut-- >= 0)) вы всегда будете выходить по таймауту, потому что jms сообщение в "... Далее отправка" так и не отправиться
...
Рейтинг: 0 / 0
25 сообщений из 43, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронный вызов через JMS
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]