Как запустить задачу с фиксированными интервалами в нескольких экземплярах Tomcat env.? - PullRequest
3 голосов
/ 05 марта 2012

Я планирую запуск фоновой задачи с фиксированными интервалами, но, так как tomcat запускается в нескольких экземплярах (т. Е. При запуске нескольких серверов Apache; в моем случае - 3), тогда задача запускается 3 раза в каждом интервале.нравится запускать один раз (независимо от количества запущенных экземпляров Tomcat).

Я запускаю сервлет, загруженный при запуске (в web.xml), который инициирует мою задачу:

<servlet>
    <servlet-name>OnInit</servlet-name>
    <servlet-class>box.OnInit</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet> 

Класс OnInit инициирует один экземпляр этого класса:

public class BGTaskRefresh {
    private static BGTaskRefresh refreshTaskFactory = null;
    private final Timer timer = new Timer();

    public BGTaskRefresh() {}
    public static void init()
    {
        if( refreshTaskFactory == null )
        {
            refreshTaskFactory = new BGTaskRefresh();
            refreshTaskFactory.start();
        }
    }

    public void start() 
    {
        timer.schedule(
            new TimerTask() 
            {
                    public void run() 
                    {
                        boxService box = new boxService();
                        box.refreshMethod();
                    } 
                },                      
                5 * 60 * 1000,   // 5-Min Delay for first run
            60 * 60 * 1000); // 60-Mins (Interval between 2 runs)                   
    }
}

Ответы [ 2 ]

3 голосов
/ 05 марта 2012

Возможно, вы захотите взглянуть на , особенно на его возможности кластеризация :

две куклы http://quartz -scheduler.org/images/documentation/2.x/quartz_cluster.png

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

Другой вариант - и распределенные блокировки и очереди, которые он предоставляет.

0 голосов
/ 05 марта 2012

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

Вот одна статья, которую я нашел с техникой блокировки на основе БД: http://blog.udby.com/archives/15

...