Потенциальные ловушки при использовании очереди JMS?
Мне было предложено разработать и внедрить систему для получения большого объема автоматизированных данных датчиков с большого количества устройств. Эти данные будут создаваться через регулярные промежутки времени и отправляться на сервер в виде xml в сообщении http. Устройства будут пересылать одни и те же данные, если они не получат определенное подтверждение от сервера. Некоторая потенциально тяжелая обработка этих данных должна произойти до того, как она будет вставлена в несколько таблиц в основной базе данных через транзакцию, и, кроме того, некоторые точки данных должны быть выделены для перенаправления на другие внешние URL-адреса.
Я планирую использовать сервер приложений Java (опираясь на GlassFish) с сервлетом для приема входящих данных. Я хотел бы реализовать какой-то механизм очередей для временного хранения данных, чтобы ответ обратно на датчик не зависел от всей промежуточной обработки. Отдельные независимые очереди также являются требованием для части реверсирования данных. После выполнения некоторых исследований два основных варианта:
1) Установите базу данных на сервере приложений и используйте таблицы для различных очередей. Очереди будут обрабатываться Java-приложением, либо запущенным на сервере приложений, либо автономным, так как он является собственной службой.
2) Используйте JMS-решение, поддерживающее базу данных, для реализации очереди.
Я не знаком с JMS, но из того, что я прочитал, похоже, это лучшее решение в этом случае. Основным требованием является то, что никакие данные датчика никогда не теряются или не выпадают из очереди перед обработкой и что они будут обрабатываться более или менее последовательно. Мы также хотели бы упростить процесс обработки некоторых очередей в определенное время, но при этом они накапливают данные, и эти сообщения никогда не истекают автоматически.
Со стратегией 1 мне очевидно, как удовлетворить эти требования, но она может быть менее надежной и масштабируемой и сложнее разрабатывать, чем стратегия 2, так как мне нужно будет написать свой собственный многопоточный код для обработки различных независимые очереди. Мне интересно, какие потенциальные ловушки могут быть в использовании JMS-очередей для этой цели, так как я никогда с ними не работал.
Целостность данных - большая проблема, поэтому мне нужно убедиться, что JMS не гарантирует потери данных в случае перезагрузки сервера, отключения питания или если по какой-то причине очередь становится очень большой. Например, может возникнуть проблема с завершением транзакций в основной базе данных в течение определенного периода времени, что может привести к тому, что JVM закончит работу с памятью, сбой и потеряет все накопленные данные? (Это будет сценарий кошмара).
Кроме того, мне было интересно, будет ли какой-либо способ приостановить обработку очереди JMS с помощью администратора приложения для сервера приложений или легко увидеть, что в очереди (я бы включил объект, который будет представлять собой сообщение xml плюс некоторые другие данные, включая полученную временную метку и т.д.). Я прочитал несколько сообщений, посвященных связанным с ними вопросам, но хотел получить прямую обратную связь. В основном я хотел бы знать примеры (если они есть), где JMS не является подходящим решением для очередей и если это один из этих случаев. Любые советы приветствуются.
Ответы
Ответ 1
Калеб отвечает на разговоры о преимуществах JMS довольно красноречиво, но так как вы спрашиваете о ловушках, вот о чем я могу думать.
- Не все реализации JMS равны. Теоретически вы можете использовать любую реализацию в соответствии с вашими потребностями, но если вы не готовы выполнить какое-то серьезное тестирование нагрузки и тестирование отказа, вы не можете знать, что конкретная реализация не будет терпеть неудачу в вашем конкретном случае использования.
- Большинство JMS используют транзакционное хранилище данных, такое как реляционная база данных, как их задняя часть. Это означает, что вместо того, чтобы напрямую писать в какой-либо хранилище данных, вам нужно полагаться на дополнительный уровень реализации JMS между вами и этими сохраненными сообщениями.
- При замене реализаций JMS, чтобы найти тот, который идеально соответствует вашим потребностям, может показаться простой задачей из-за однородного JMS API, критических функций для обработки ошибок, мониторинга JMS-сервера и всех других интересных вещей, которые существуют выше и помимо обмена сообщениями, это будет проблемой, если вы измените свою реализацию.
Тем не менее, я думаю, вы были бы сумасшедшими, чтобы писать в БД самостоятельно, вместо того, чтобы идти с JMS. В первом случае ActiveMQ - почтенный JMS-сервер, используемый во многих корпоративных средах. Во-вторых, факт заключается в том, что вы просто закончите писать этот дополнительный слой самостоятельно, чтобы реализовать обмен сообщениями, и ваш код не будет иметь преимуществ тысяч глаз (или набора платных разработчиков, которые выполняют единственную работу реагировать на запросы клиентов и следить за тем, чтобы реализация JMS была прочной). В третьем пункте, точно так же, как и в случае с вашим backend-хранилищем данных. Используйте JMS, вы сэкономите свои проблемы в долгосрочной перспективе.
Ответ 2
Если вы хотите пройти JMS-маршрут, хорошим выбором будет автономный JMS-совместимый брокер сообщений (отдельно от вашего сервера приложений). Брокеры сообщений варьируются от свободного открытого источника (например, ActiveMQ в http://activemq.apache.org/ или OpenMQ в https://mq.dev.java.net/), к крупным коммерческим решениям (IBM WebSphere MQ at http://www-01.ibm.com/software/integration/wmq/ является одним из самый большой).
Брокеры сообщений предлагают гарантированную доставку (при условии, что сервер работает и прослушивается), и вы можете сделать совсем немного, чтобы гарантировать, что система отказоустойчива, включая встроенные серверы резервного брокера и мгновенное резервное копирование. Очереди брокеров могут, в конечном счете, выйти из комнаты, если ваш сервер приложений не собирает сообщения, но вы можете назначить огромную глубину очереди (100 ГБ) и отправить предупреждения о сервере, если сообщения не обрабатываются, а очередь достигает определенный процент.
Ваше приложение Java затем будет запускаться на другом сервере целиком и будет подключаться к брокеру и вытаскивать сообщения из очереди как можно быстрее. Если сервер приложений выйдет из строя или перестанет собирать сообщения по любой другой причине, брокер просто сохранит все сообщения в этой очереди, пока сервер приложений не начнет их снова собирать.