Каков наилучший способ непрерывной обработки асинхронной очереди в Java? - PullRequest
7 голосов
/ 05 февраля 2009

Мне трудно понять, как спроектировать последний фрагмент моей системы. В настоящее время я использую сервер Tomcat с сервлетом, который отвечает на запросы клиентов. Каждый запрос в свою очередь добавляет сообщение обработки в асинхронную очередь (вероятно, я буду использовать JMS через Spring или, скорее всего, Amazon SQS).

Последовательность событий такая:

Сторона отправки:
1. Примите запрос клиента
2. Добавьте в БД некоторые данные, связанные с этим запросом, с уникальным идентификатором
3. Добавьте объект сообщения, представляющий этот запрос, в очередь сообщений

Принимающая сторона:
1. Извлечь новый объект сообщения из очереди
2. Разверните объект и получите некоторую информацию с веб-сайта на основе информации, содержащейся в объекте msg.
3. Отправить оповещение по электронной почте
4. обновите строку моей БД (с тем же уникальным идентификатором) информацией о том, что операция была выполнена для этого запроса.

Мне трудно понять, как правильно поступить с принимающей стороной. С одной стороны, я, вероятно, могу создать простую Java-программу, которую я запускаю из командной строки, которая выбирает каждый элемент в очереди и обрабатывает его. Это безопасно? Имеет ли смысл запускать эту программу как другой поток внутри контейнера Tomcat? Я не хочу делать это последовательно, то есть принимающая сторона должна иметь возможность обрабатывать несколько объектов одновременно, используя несколько потоков. Я хочу, чтобы это работало всегда, 24 часа в сутки.

Какие есть варианты построения принимающей стороны?

Ответы [ 4 ]

3 голосов
/ 05 февраля 2009

"С одной стороны, я могу, вероятно, создать простую программу Java, которую я запускаю из командной строки, которая выбирает каждый элемент в очереди и обрабатывает его. Это безопасно?"

Что в этом опасного? Отлично работает.

"Имеет ли смысл запускать эту программу как другой поток внутри контейнера Tomcat?"

Только если у Tomcat достаточно свободного времени для фоновой обработки. Зачастую это является случаем - у вас есть свободное время для такой обработки.

Тем не менее, потоки не являются оптимальными. Потоки используют общие ресурсы ввода-вывода, и ваш фоновый поток может замедлять работу внешнего интерфейса.

Лучше иметь очередь JMS между внешним интерфейсом "порт 80" и отдельным внутренним процессом. Внутренний процесс запускается, подключается к очереди, извлекает и выполняет запросы. Внутренний процесс может (при необходимости) быть многопоточным.

2 голосов
/ 05 февраля 2009

Если вы используете JMS, почему вы помещаете задачи в БД?

Вы можете использовать долговременную очередь в JMS. Это сохранит задачи, даже если JMS-брокер умрет, пока они не будут подтверждены. Вы можете иметь избыточных брокеров, так что если один из них умирает, второй автоматически вступает во владение. Это может быть более надежным, чем использование одной БД.

1 голос
/ 05 февраля 2009

Если вы уже используете Spring, проверьте DefaultMessageListenerContainer . Это позволяет вам создавать бин, управляемый сообщениями POJO. Это можно использовать из существующего контейнера приложения (файл WAR) или как отдельный процесс.

0 голосов
/ 05 февраля 2009

Я сделал это, разместив приемник на сервере приложений, в моем случае - weblogic, но tomcat тоже отлично работает. Не опрашивайте очередь, используйте модель, основанную на событиях. Это может быть ручной код или веб-служба, управляемая сообщениями. Если обновление базы данных идемпотентно, вы можете обновить базу данных и отправить электронное письмо, а затем выполнить фиксацию в очереди. Это не проблема иметь несколько потоков, которые все читают из одной и той же очереди.

Я использую различные решения JMS, в том числе tibco, activemq (до того, как его включил apache) и joram. Joram был более надежным решением с открытым исходным кодом, но это могло измениться теперь, когда он стал частью Apache.

...