Поведение EJB TimerService

У меня есть приложение, работающее с TimerService, я создаю несколько таймеров для выполнения определенных задач. Он работает нормально. Однако я замечаю некоторую задержку в тайм-аутах. У меня есть тайм-аут «A», который должен запускаться каждые 10 минут, а другой «B» - каждые 3 минуты. Если «А» выполняется 5 минут, «Б» запустится только после окончания «А», что приведет к задержке на 2 минуты. Это проблема, потому что вещи не готовы, когда должны быть. Мой вопрос в том, есть ли способ запуска TimerService одновременно. Фрагменты кода, которые я использую, приведены ниже. Я ценю любую помощь.

Создание расписания:

// Every schedule extend from this class.
public abstract class Schedule {
@Resource
private TimerService timerService;

public void start() {
        TimerConfig timerConfig = new TimerConfig();
        timerConfig.setInfo(name);
        timerConfig.setPersistent(false);
        timerService
                .createCalendarTimer(this.calendarSchedule, timerConfig);
}

}

Реализация графика:

@Named
@Stateless 
public class MyScheduleEJB extends Schedule {
   @Timeout
   public void timeout(Timer timer) {
    // do the work
   }
 }

person Jorge Iten Jr    schedule 15.07.2013    source источник
comment
Таймеры должны работать независимо, используя отдельные экземпляры сеансовых компонентов без сохранения состояния. Если вы добавите ведение журнала к методам тайм-аута, увидите ли вы, что оба метода обратного вызова тайм-аута запускаются, но заканчиваются последовательно, или один даже не запускается, пока не завершится другой? Используете ли вы какие-либо синхронизированные методы или блокировки? Оба метода тайм-аута работают с одной и той же БД и блокируются блокировками БД? Настроили ли вы размер пула bean-компонентов без сохранения состояния, чтобы разрешить только один экземпляр bean-компонента?   -  person Brett Kail    schedule 15.07.2013
comment
Я начал проверять ваши вопросы и нашел для этого конкретную конфигурацию в Websphere. Спасибо.   -  person Jorge Iten Jr    schedule 16.07.2013
comment
Ах, я совсем забыл эту настройку. Хорошая находка.   -  person Brett Kail    schedule 17.07.2013
comment
Из отладки моего собственного кода в JBoss7.2 я обнаружил, что каждый компонент имеет свой собственный поток для выполнения таймеров, но все тайм-ауты компонента будут выполняться в одном и том же потоке (это выглядит так, даже если компонент не является одноэлементным компонентом без сохранения состояния) . У моего bean-компонента было 2 отдельных таймера, и он выдал некоторое исключение параллелизма, из-за которого он не мог выполнить тайм-аут, пока другой уже работал. Я смог позволить моему работать параллельно, разделив его на 2 bean-компонента (что я должен был сделать в любом случае). Не знаю, ведет себя вебсфера так же или нет.   -  person Shadow Man    schedule 18.12.2013


Ответы (2)


Это очень специфическая ситуация на сервере приложений. Но если у кого-то еще есть такая же проблема, в Websphere есть конфигурация (не уверен в других AS), которая сообщает, сколько потоков должны использовать пулы таймеров. По умолчанию только 1, поэтому он не работал одновременно. Конфигурация:WAS Config

person Jorge Iten Jr    schedule 16.07.2013

Я вижу здесь две проблемы:

Во-первых, почему вы используете метод createCalendarTimer? Я думаю, что наиболее подходящим методом TimerService для ваших требований (для выполнения каждые 5 или 10 секунд) является createIntervalTimer.

Во-вторых, я думаю, что то, как вы реализуете свой таймер EJB, не соответствует спецификации EJB.

Он говорит:

18.2 Представление поставщика компонентов службы таймера

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

18.3 Обязанности поставщика компонента

Корпоративный компонент, который должен быть зарегистрирован в службе таймера, должен иметь метод обратного вызова с тайм-аутом. Класс корпоративного компонента может иметь суперклассы и/или суперинтерфейсы. Если у класса компонента есть суперклассы, метод тайм-аута может быть определен в классе компонента или в любом из его суперклассов.

Как видите, существуют некоторые ограничения на реализацию таймера EJB. Вероятно, спецификация имеет несколько интерпретаций, но после прочтения этого я без колебаний изменю свой код.

person Gabriel Aramburu    schedule 15.07.2013
comment
Во-первых, это был просто пример, для моих нужд (создание расписания для определенных дней недели в разные часы) createCalendarTimer является наиболее подходящим. - person Jorge Iten Jr; 16.07.2013
comment
Во-вторых, я не понимаю вашу точку зрения, мой код не нарушает того, что вы написали. Спасибо. - person Jorge Iten Jr; 16.07.2013