Использование клиентской сессии JMS

Я пытаюсь использовать клиент.NET Kaazing для взаимодействия с серверной частью JMS через веб-сокеты. Я изо всех сил пытаюсь понять правильное использование сессий. Первоначально у меня был один сеанс, общий для всех потоков, но я заметил, что это не поддерживается:

Объект Session - это однопоточный контекст для создания и потребления сообщений. Хотя он может выделять ресурсы поставщика вне виртуальной машины Java (JVM), он считается легким объектом JMS.

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

Когда я попытался создать несколько сессий, я получил ошибку:

System.NotSupportedException: Only one non-transacted session can be active at a time

Поиск этой ошибки был безрезультатным, поэтому я попытался переключиться на сеансы с транзакциями. Но при попытке создать потребителя я получаю другую ошибку:

System.NotSupportedException: This operation is not supported in transacted sessions

Кажется, я застрял между камнем и наковальней. Единственными возможными вариантами, которые я вижу, является разделение моего сеанса между потоками или использование одного нетранзакционного сеанса, используемого для создания потребителей, и нескольких транзакционных сеансов для всего остального. Оба эти подхода кажутся мне немного противными.

Может ли кто-нибудь пролить свет на правильный способ обработки сеансов в моем клиенте?

1 ответ

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

  1. Подход на основе задач будет использовать TaskScheduler. В Message Listener задача будет запланирована для обработки работы и немедленного возврата. Например, вы можете запланировать новую задачу для каждого сообщения. В этот момент Message Listener вернется, и следующее сообщение будет немедленно доступно. Этот подход подходит для приложений с низкой пропускной способностью - например, несколько сообщений в секунду - но там, где вам нужен параллелизм, возможно, потому что некоторые сообщения могут занимать много времени для обработки.

  2. Другой подход заключается в использовании структуры данных сообщений для ожидающей работы ( ConcurrentQueue). Когда вызывается Message Listener, каждое сообщение добавляется в ConcurrentQueue и немедленно возвращается. Затем отдельный набор потоков / задач может извлекать сообщения из этого ConcurrectQueue, используя подходящую стратегию для вашего приложения. Это будет работать для более высокой производительности приложения.

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

Обратите внимание, что если вы используете JMS Queues, каждое сообщение будет подтверждено неявно, когда ваш Message Listener вернется. Это может или не может быть поведение, которое вы хотите для вашего приложения.

Для приложений с более высокой производительностью следует рассмотреть подходы 2 и 3.

Другие вопросы по тегам