#java #ejb #wildfly #ejb-3.1 #timertask
#java #ejb #wildfly #ejb-3.1 #timertask
Вопрос:
Я использую службу автоматического таймера EJB с аннотацией @schedule. Однако мне нужна помощь в следующем.
Мне нужна служба одноэлементного времени (выполнение только на одном узле в кластере), но я не хочу выполнять пропущенные таймеры во время перезапуска или сбоя сервера.
Я прочитал много статей, но все упоминают о постоянных таймерах для достижения одноэлементного поведения в кластерной среде.
Мой код:
@Singleton
@Startup
public class DataService {
@Schedule(second="*/10", minute="*", hour="*", persistent=false)
public void xxxFetch() {
// business logic
}
}
Есть ли способ добиться одноэлементного обслуживания с непостоянными таймерами?
Ответ №1:
Это поведение определено в спецификации EJB 3.2 (разделы 13.2.2, 13.2.3, 13.2.4 и 13.4.4).
Существует два типа таймеров: автоматически созданные таймеры (с аннотациями) или программно аннотированные таймеры (с использованием TimerService
). Оба могут быть постоянными или непостоянными.
- Постоянные таймеры (как автоматически, так и созданные программно) будут выполняться только в одном узле.
- Непостоянные автоматически созданные таймеры будут выполняться на каждом узле в кластере.
- Непостоянные программно созданные таймеры будут запускаться только на том узле, на котором они созданы.
Итак, чтобы создать одноэлементную службу с непостоянными таймерами, вам нужно установить какую-то конфигурацию или запустить запрос на одном из узлов, чтобы он программно создавал таймер.
Но имейте в виду, что если этот узел выйдет из строя, служба таймера не будет выполнена.
Такого же поведения можно добиться, выполнив задачу в a ManagedScheduledExecutorService
с новой Concurrency for Java EE
спецификацией. Но IMO это не дает никаких преимуществ программному созданию непостоянного таймера с TimerService
помощью . Совсем наоборот: создание таймера является транзакционной операцией, а планирование задачи — нет.
Однако существует функция Wildfly, которая может удовлетворить ваши потребности: высокодоступные одноэлементные развертывания.
Вы можете определить модуль как одноэлементное развертывание. Этот модуль развернут в кластере, но он активен только на одном узле. Если этот узел выходит из строя, модуль активируется на другом узле.
Таким образом, вы можете поместить свои EJB
автоматически или программно созданные таймеры в одноэлементный модуль, и вы получите как выполнение на одном узле, так и высокую доступность.
Комментарии:
1. любые альтернативы, такие как использование ManagedScheduledExecutorService?
2. с помощью a
ManagedSheduledExecutorService
вы можете добиться того же поведения, что и непостоянный таймер, созданный программноTimerService
. Но ИМО это не дает никаких преимуществ, совсем наоборот: создание таймера является транзакционным, а планирование задачи — нет.3. Я добавил информацию о функции wildfly, которая может удовлетворить ваши потребности: HA одноэлементные развертывания
4. Одноэлементные развертывания HA предназначены для всего файла ear / war. Как мы можем создать одноэлементный сервис для одной службы в EAR?
5. Согласно документу wildfly, вы не можете. «Этот дескриптор может быть применен к любому типу развертывания, например, JAR, WAR, EAR и т. Д., За исключением вложенного развертывания в EAR». Вам нужно извлечь свой EJB в отдельный JAR и развернуть этот JAR как одноэлементный.