Статус

КомментарийДополнительный комментарий

Если из метода runAgent "самостоятельного агента" выброшено исключение (кроме InterruptedException), то КМА отсылает протокол сбоя в МА и завершает его исполнение.

Если исключение выброшено из агента, обрабатывающего JMS-сообщения, необходимо откатить транзакцию. Обязательно вызвать userTransaction.setRollbackOnly() иначе сообщение не будет доставлено повторно и нельзя пересоздавать Consumer, т.к. следующие сообщения в очереди будут доставляться другому Consumer после значительной паузы. Если агент по-расписанию - его надо сразу же перезапустить, чтобы он продолжил обработку следующих сообщений, параллельно отправляя протокол сбоя в МА.

Сообщение, при обработке которого произошел сбой, будет доставлено повторно произвольному КМА через некоторую паузу. Порядок доставки сообщений в таком сценарии нарушится. Определить, что сообщение доставлено повторно можно через св-во Message.getJMSRedelivered().

Сбой при обработке сообщения может быть обусловлен разными факторами

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

Временные факторы можно решить повторным перезапуском агента и повторной доставкой (redelivery) сообщения. Но в случае постоянных факторов redelivery и частый перезапуск агента может приводить к огромному потреблению вычислительных ресурсов в холостую.

Artemis решает задачу повторной доставки сообщения если настроить отложенную передоставку. По умолчанию, передоставка осуществляется моментально и тому же КМА, что в случае сбоя, обусловленного именно сообщением, не позволит обработать следующие сообщения достаточно длительный интервал времени. Очередь Artemis можно настроить так, что передоставка будет осуществляеться через таймаут, который геометрически растет после каждой неудачной доставки. Передоставка чаще всего происходит на тот же самый КМА, но может и на любой другой. После заданного числа повторов (по умолчанию 10), сообщение будет перемещено в очередь мертвых сообщений (DLQ). В сообщение при этом добавляются заголовки с именем JMS-Очереди (address в терминах Artemis) и именем подписки (queue в терминах Artemis). Имя подписки совпадает с идентификатором НЗ. Так что данных достаточно для перенаправления сообщения конкретной НЗ.

Детектируемые агентом сбои должны быть оформлены специальным unchecked исключением TemporaryUnavailabeException, выбрасываемым агентом. Данный эксепшен от агента сообщает КМА, что текущее сообщение требуется передоставить позже. Если агент "по расписанию", то КМА должен откатить транзакцию обработки последнего сообщения (setRollbackOnly и rollback) и заново запустить агент для обработки последующих сообщений. Сбойное сообщение МОМ доставит позже в соответствии со своими настройками.

"Предохранитель"

При постоянном сбое, КМА должен перестать перезапускать агент и отправить в МА сигнал о прерывании исполнения НЗ. Если НЗ в режиме ANY, то МА должен отключить НЗ, предотвращая тем самым повторный запуск сбойного агента. Если режим MANY, то НЗ отключается если сообщение о прерывании пришло от 2 или более разных серверов. При отключении НЗ ASAP-MANY или DELAYED-MANY агента, надо остановить его исполнение на всех прочих серверах пула. Для этого МА должен послать сообщение КМА для остановки агентов по НЗ

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

Отключение агента, помимо экономии вычислительных ресурсов, позволит MOM прекратить доставку сообщений экземплярам сбойного агента, а значит будет меньше поводов перемещать сообщения в DLQ. Другой неприятный эффект у Artemis, что сообщения с не подтвержденной доставкой быстро съедают память Artemis. Предохранитель снизит число не подтвержденных сообщений и выедание памяти. Доставка сообщений возобновится после исправления агента и включения НЗ.

Для определения "постоянных сбоев" предлагается следующая эвристика. КМА ведет счетчик перезапусков агента после сбоя (исключая TemporaryUnavailabeException). КМА должен отключить "настройку запуска", если произошло N сбоев подряд с одним типом исключения или M сбоев подряд, но с разными типами исключений (N<M. По умолчанию N = 3, M = 10). Параметр M должен определяться в НЗ. Параметр N вычисляться как 1/3 от M.

Dead Letter Queue

Очередь DLQ необходимо сделать durable. Для возвращения сообщений из очереди DLQ в обработку в Web-консоли Artemis есть специальная групповая операция. Причем, сообщение возвращается не в общую очередь, а в очередь для конкретной НЗ агента, при работе которого и произошел сбой, приведший к попаданию в DLQ

Каждое сообщение можно просмотреть в отдельности

Протоколирование сбоев

Каждый сбой (исключение), отловленный КМА, необходимо запротоколировать в МА. В МА протоколы сбоев должны отображаться сгруппированными по каждой активации НЗ и по серверам. Для этого МА в сигнале на запуск агента должен передать "идентификатор активации" (удобно использовать текущее время МА или UUID). КМА во всех сообщениях для МА, связанных с исполнением НЗ, должен передавать и этот "идентификатор активации" и имя сервера.

Протоколы сбоев должны периодически удаляться. Если статус завершения последней активации НЗ - "выполнен успешно", то удаляются все протоколы сбоев. Если статус "завершен с ошибкой", то удаляются протоколы старше N дней от даты последней активации.

Статус "в работе" не является статусом завершения последней активации. Он относится к следующей активации.