Задача: Читать сообщения пачками из jms очереди, делать обработку, применять какую-либо логику уже на пачку.

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

Для решения этой задачи есть несколько вариантов:

  1. Apache Camel. Все можно сделать почти из коробки. Есть компонент SJMS он умеет читать пачками jms сообщения, можно задать таймаут и максимальный размер пачки.
  2. Spring JmsTemplate + Spring Batch. Собственно более тяжелый вариант, относительно 1, но довольно интересный.

Общая модель работы фреймворка

  1. Создаем Reader и Writer. Объекты которые будут что-то вычитывать и записывать соответственно. В моем примере Reader — читает jms. Writer — просто выводит в консоль всю пачку. Глобально это могут быть самые разнообразные операции. Spring-Batch укомплектован самыми различными реализациями, но при необходимости добавить что-то свое, не составит труда.
  2. Создаем Processor — он может выполнять любую бизнес логику над данными, полученными из Reader. Тут нужно обратить внимание, что processor применяется до формирования пачки.
  3. После создаются шаги Step из которых собирается Job. Здесь и начинается работа. Spring запускает job на выполнение, он работает пока не reader не вычитает все данные. Признак конца — возврат null.

Реализация

Для начала нужно создать проект. Удобней всего это сделать из архетипа spring-boot.

После создания нужно добавить зависимости:

Отмечу, что jmsTemplate и scheduling (интервальный запуск) уже входят в spring-boot.

Сконфигурируем reader, writer, processor и создадим job.

Добавим запуск каждые n-секунд, используя аннотацию @Scheduled

Единственно чего не хватает — транзакционности. Если упадем на обработке или записи, потеряем всю вычитанную пачку.


Ссылки:


Ссылка на проект в GitHub: sboychenko/spring-batch-jms-test