【问题标题】:Execute a Quartz Job only once in a multi-instance environment在多实例环境中只执行一次 Quartz Job
【发布时间】:2019-08-06 00:04:29
【问题描述】:

我正在尝试在 Quartz 1.6 中创建一个 Job,但只需要执行一次,因为我有两个具有相同版本的 .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

【问题讨论】:

  • 你能分享一下quartz.properties 文件吗?另外,请检查数据库表中的作业条目,了解它显示了多少作业实例?
  • 另外,请注意@DisallowConcurrentExecution,据说是为了迎合单个节点上的单个作业执行。对于多个节点,石英集群负责。
  • 声明 necessity to execute only oncewill be executed every 60 seconds 相互排斥。请澄清所需的行为
  • @Ankur 我添加了石英属性文件。

标签: java quartz-scheduler quartz


【解决方案1】:

您需要将以下属性添加到您的quartz.property 文件中(来源:click here):

org.quartz.jobStore.isClustered : true

阅读本文以了解有关isClustered 属性的更多信息,请参阅this 链接。

请注意:

@DisallowConcurrentExecution 在您有 2 个不同作业且在同一节点上运行具有相同作业密钥的作业时有效。

而 isClustered 属性用于确保在应用程序运行多个节点时执行作业的单个实例,这些节点通过数据库表进行通信以实现原子性。

【讨论】:

  • 为了安全起见,我们需要设置 org.quartz.scheduler.instanceId=AUTO 因为石英中的集群是在数据库级别完成的。如果石英的两个实例具有相同的名称,即 ( org.quartz.scheduler.instanceName) 但不同的 instanceId (org.quartz.scheduler.instanceId) 会形成一个集群。
  • 我在项目中添加了quartz jar,quartz.properties文件在里面,当我执行Job时会自动识别?
  • @AnkurisClustered: true 适用于 Quartz 的多个实例还是我们应用程序的多个实例?我检查了您提供的参考资料,这里将 IsClustered 标志设置为“true”以打开集群功能。如果您有多个 Quartz 实例使用同一组数据库表,则此属性必须设置为“true”……否则,您将遇到严重破坏。有关更多信息,请参阅集群配置文档。
猜你喜欢
  • 2016-04-28
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多