возможно ли создать одноэлементный непостоянный таймер ejb?

#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 как одноэлементный.