Выполнить задание Quartz только один раз в среде с несколькими экземплярами

Я пытаюсь создать Job в Quartz 1.6, но с необходимостью выполнить только один раз, потому что у меня есть два тестовых экземпляра с одинаковой версией файла .war.

Это мой TestPlugin класс, Job будет выполняться каждые 60 секунд:

public class TestPlugin implements PlugIn {

    public TestPlugin() {
        super();
    }

    public void destroy() {
    }

    public void init(ActionServlet arg0, ModuleConfig arg1)
            throws ServletException {

        try {
            JobDetail job = JobBuilder.newJob(TestDemonio.class)
                    .withIdentity("anyJobName", "group1").build();
            Trigger trigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity("anyTriggerName", "group1")
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/60 * * ? * * *"))
                    .build();

            Scheduler scheduler = new StdSchedulerFactory().getScheduler();
            scheduler.scheduleJob(job, trigger);
            scheduler.start();

        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

Затем у меня есть класс TestExecute для вывода простого вывода:

@DisallowConcurrentExecution
public class TestDemonio implements Job {

    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("QUARTZ JOB MESSAGE");
    }
}

Я исследовал, как достичь желаемого, добавив аннотацию @DisallowConcurrentExecution, чтобы выполнить задание только один раз, но я получаю сообщение, которое печатается в каждом экземпляре.

Это мой файл quartz.properties:

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000

org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore

person TimeToCode    schedule 06.08.2019    source источник
comment
не могли бы вы также поделиться файлом quartz.properties? Кроме того, проверьте записи о вакансиях в таблицах базы данных, сколько экземпляров вакансий отображается?   -  person Ankur    schedule 06.08.2019
comment
Также обратите внимание, что @DisallowConcurrentExecution, предположительно, обслуживает выполнение одного задания на одном узле. За несколько узлов отвечает кварцевая кластеризация.   -  person Ankur    schedule 06.08.2019
comment
Утверждения necessity to execute only once и will be executed every 60 seconds исключают друг друга. Пожалуйста, поясните желаемое поведение   -  person Nikolai Shevchenko    schedule 06.08.2019
comment
@Ankur Я добавил файл свойств кварца.   -  person TimeToCode    schedule 06.08.2019


Ответы (1)


Вам необходимо добавить следующее свойство в свой файл quartz.property (источник: щелкните здесь):

org.quartz.jobStore.isClustered : true

Прочтите это для получения дополнительной информации о свойстве isClustered, обратитесь к этому ссылка.

Пожалуйста, обрати внимание:

@DisallowConcurrentExecution работает, когда у вас есть 2 разных задания с одним и тем же ключом задания, запущенным на одном узле.

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

person Ankur    schedule 07.08.2019
comment
Чтобы быть в безопасности, нам нужно установить org.quartz.scheduler.instanceId = AUTO, поскольку кластеризация в кварце выполняется на уровне базы данных. Если два экземпляра кварца имеют одинаковое имя, то это (org.quartz.scheduler.instanceName) но с другим instanceId (org.quartz.scheduler.instanceId) они будут формировать кластер. - person user06062019; 07.08.2019
comment
Я добавил в проект кварцевую банку, внутри находится файл quartz.properties, когда я выполню задание, он будет автоматически распознан? - person TimeToCode; 07.08.2019
comment
@ Ankur- isClustered: true для нескольких экземпляров Quartz или нескольких экземпляров нашего приложения? Я проверил ссылку, которую вы дали, и здесь написано для флага IsClustered. Установите значение «true», чтобы включить функции кластеризации. Это свойство должно быть установлено в «true», если у вас несколько экземпляров Quartz используют один и тот же набор таблиц базы данных… в противном случае вы испытаете хаос. Дополнительную информацию см. В документации по настройке кластеризации. - person Vipul Jain; 23.02.2021