Как сделать Jms Listener Bean не-синглтоном? - PullRequest
0 голосов
/ 31 октября 2019

Мы переписываем службу на основе J2EE, которая работает в Websphere AS, и теперь используем Spring 5.1 / Spring Boot 2.1 с Tomcat в качестве целевой платформы. Служба получает свои запросы через IBM MQ (с фиксированным числом очередей запросов для разных клиентов) и отправляет ответы, используя соответствующие очереди ответов.

Одна важная часть реализации J2EE заключается в том, что для каждой входной очереди имеется настраиваемое количество MDB, которые обрабатывают запросы параллельно (что соответствует клиентскому количеству соединений с серверной системой, используемой для обработки. ).

В нашей новой реализации Spring мы используем один DefaultJmsListenerContainerFactory и несколько классов @Component, каждый с аннотированным методом @JmsListener. Все работает нормально, пока мы ограничиваемся последовательной обработкой сообщений: Concurency равен 1, а компоненты singleton обрабатывают одно сообщение за другим.

Если мы повышаем значение параллелизма, мы получаем ожидаемую проблему: так как нашbean-компоненты синглтон-слушателя не являются поточно-ориентированными, параллельная обработка сообщений создает хаос. Мы подумали, что самым простым решением было бы использовать несколько экземпляров каждого компонента-слушателя (как мы это делали с MDB в J2EE), поэтому мы аннотировали классы компонента-слушателя с помощью @Scope ("prototype").

Результатбыло разочарование: больше не было никакой обработки сообщений! В файле журнала мы видим только «Создание общего экземпляра синглтон-компонента» (почему синглтон ??), но не выводим журнал из конструктора и не выводим сообщение об ошибке, поэтому ясно, что компоненты-слушатели не были созданы должным образом,Затем мы попробовали SimpleThreadScope вместо области действия прототипа, но, несмотря на правильную регистрацию, это привело к той же проблеме.

Я попытался проверить, возникла ли эта проблема где-либо еще, и нашел только один случай (https://github.com/spring-projects/spring-framework/issues/18045),, нонерешенная проблема была закрыта по неизвестным причинам.

Это ошибка или я слишком оптимистичен, чтобы требовать несколько экземпляров компонента-слушателя, изменяя @Scope?

1 Ответ

1 голос
/ 31 октября 2019

Больше не было обработки сообщений!

Вам нужно вызвать applicationContext.getBean("myBeanWithAJmsListener") n раз, чтобы создать n экземпляров вашего слушателя. Сделайте это после того, как контекст инициализирован;например, в ApplicationRunner, если вы используете Spring Boot.

Бины-прототипы не создаются автоматически.

Вы несете ответственность за destroy() экземпляры во время завершения работы.

См. этот ответ для примера - в этом случае каждый экземпляр прослушивает свою очередь.

...