Сохранение таймера JEE6 при повторном развертывании

#timer #java-ee-6 #ejb-3.1

#таймер #java-ee-6 #ejb-3.1

Вопрос:

Одной из задач приложения, которое я разрабатываю, является резервное копирование данных других приложений, запущенных в системе. Я хочу запланировать этот процесс резервного копирования, чтобы он мог выполняться без присмотра. Я использую утилиты таймера JEE6 / EJB3.1.

У меня есть класс BackupConfiguration, который я сохраняю в базе данных с использованием JPA2, который имеет поле типа TimerHandle. Если пользователь решает запланировать резервное копирование, я создаю новый постоянный таймер и заполняю поле TimerHandle.

Если я перезапущу сервер, все будет в порядке, таймеры перезапустятся (и возникает краткая паника, поскольку все таймеры срабатывают одновременно, вздох), и все так, как я оставил.

Если я повторно разверну приложение (что происходит довольно часто, пока я его разрабатываю), все таймеры будут потеряны! Я глупо предположил, что таймеры будут привязаны к серверу, но оказывается, что они привязаны к приложению.

Итак, мой вопрос: каков наилучший способ сделать таймеры постоянными при повторном развертывании?

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

Комментарии:

1. Какой сервер приложений вы используете? Вы описываете поведение WebSphere Application Server, но это неясно. Если вы используете сервер приложений, то я не верю, что есть возможность избежать очистки постоянных таймеров во время повторного развертывания, если только ваш сервер приложений не будет остановлен при выполнении удаления (например, с использованием отключенного сеанса wsadmin).

2. Я использую GlassFish 3.0.1, это кажется стандартным поведением.

Ответ №1:

Для GlassFish есть --keepstate=true опция asadmin redeploy команды.
Он сохраняет таймеры EJB между повторными развертываниями.
Для получения более подробной информации вы можете посмотреть:
http://docs.oracle.com/cd/E18930_01/html/821-2418/beahw.html

http://docs.oracle.com/cd/E18930_01/html/821-2416/ggndx.html#SJSASEEAGgkudf

http://docs.oracle.com/cd/E18930_01/html/821-2433/redeploy-1.html#scrolltoc

Ответ №2:

Казалось бы, большинство (вероятно, все) серверы приложений делают таймеры постоянными для приложения, а не для сервера. Это имеет смысл, поскольку при удалении приложения вы бы не хотели, чтобы таймеры зависали. Это неудобно во время разработки, потому что NetBeans, по крайней мере, удалит приложение перед повторным развертыванием, тем самым потеряв все таймеры.

Решение, которое я придумал, состоит в том, чтобы сохранить дескриптор таймера и информацию о планировании в базе данных. Когда приложение запускается, оно создает одноэлементный компонент TimerRepair, который вызывает repairTimers для любых любых классов, которые этого требуют. Метод repairTimers выбирает все расписания и, если у них есть TimerHandle, пытается восстановить таймер. Если восстановление таймера выдает исключение, оно воссоздает Таймер на основе информации о планировании. В целом это не так уж плохо как решение, моя единственная реальная проблема с этим — чрезмерное время запуска, если запланировано много элементов.