转载

如何实现Spring Boot和Quartz集成? - Nguyen Phuc Hai

调度是企业应用程序中的关键服务。您需要安排计划服务,比如向最终用户发送有关即将举行的结算活动,通知或营销活动的电子邮件通知。在Java世界中, Quartz 是流行的开源调度库,支持简单或 Cron 触发器。使用Spring boot和Quartz比直接使用内置的 Spring schedule 要有点复杂,

但是Quartz作业可以持久存储在内存或数据库中。Jobs的持久性使Quartz完美地适用于微服务架构和集群环境,您可以在多个机器中安装调度服务,并避免了标准的Spring schedule调度服务不提供与Quartz相同的强度的故障服务。

在本文中,您将学习如何在Spring启动项目中运行Quart作业。您将调度项目配置为微服务(没有Web组件),将作业持久保存到数据库并以群集模式运行。

获取完整的示例代码 https://github.com/haiphucnguyen/Quartz-Demo ,解压缩并导入您喜欢的IDE或文本编辑器。

创建Spring启动应用程序

打开https://start.spring.io/,创建新项目`quartz-demo`。将依赖项`JDBC`,`H2`,`Quartz`添加到项目中。然后生成新项目。

解压缩项目文件并将其导入IntelliJ项目。

创建计划任务

我创建了仅记录当前时间的简单计划任务:

@Component
<b>public</b> <b>class</b> ScheduleTask <b>extends</b> QuartzJobBean {
    <b>private</b> <b>static</b> <b>final</b> Logger LOG = LoggerFactory.getLogger(ScheduleTask.<b>class</b>);

    <b>private</b> <b>static</b> <b>final</b> SimpleDateFormat dateFormat = <b>new</b> SimpleDateFormat(<font>"HH:mm:ss"</font><font>);

    @Override
    <b>protected</b> <b>void</b> executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        LOG.info(</font><font>"The current time is: "</font><font> + dateFormat.format(<b>new</b> Date()));
    }
}
</font>

Quartz作业细节说明

Quartz不管理这项工作,而是通过JobDetail来完成。如果需要,您可以添加说明或作业的预定义数据。

@Bean
<b>public</b> JobDetail scheduleJob() {
  <b>return</b> JobBuilder.newJob(ScheduleTask.<b>class</b>).storeDurably()
    .withIdentity(<font>"sample_schedule"</font><font>).withDescription(</font><font>"Sample schedule task"</font><font>).build();
}
</font>

告诉Quartz什么时候运行你的作业

你需要在作业运行时告诉Quartz。Trigger类可以帮助您完成此操作。请注意,许多触发器可以指向同一个作业,但是一个触发器只有一个作业。您可以使用类TriggerBuilder来构造`Trigger`实例

@Bean
  <b>public</b> Trigger scheduleTrigger() {
    <b>return</b> newTrigger().withIdentity(<font>"trigger"</font><font>).forJob(scheduleJob()).
      withSchedule(CronScheduleBuilder.cronSchedule(</font><font>"0 * * * * ?"</font><font>)).build();
}
</font>

将调度服务作为独立应用程序运行

运行Spring启动应用程序,它会在输出中记录时间。您可能会将此应用程序视为一个调度微服务,它将执行定义任务运行时间的规则中的任务。

@SpringBootApplication
<b>public</b> <b>class</b> QuartzDemoApplication {

    <b>public</b> <b>static</b> <b>void</b> main(String[] args) {
        SpringApplication.run(QuartzDemoApplication.<b>class</b>, args);
    }
}

输出如下:

2019–03–18 19:53:43.737 INFO 46613 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552956823635 started.
2019–03–18 19:53:43.752 INFO 46613 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 36.769 seconds (JVM running <b>for</b> 37.167)
2019–03–18 19:54:00.017 INFO 46613 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:54:00
2019–03–18 19:55:00.010 INFO 46613 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:55:00

将Quartz作业保留到群集环境中的数据库

想象一下,你有调度微服务,并且你想让它运行集群环境,如果机器主机一个调度服务停机并且不使整个调度服务停止运行。在此示例中,我将Quartz配置为在群集模式下将其作业保留在H2数据库中。在`application.properties`文件中声明数据源和Quartz设置

spring.datasource.url=jdbc:h2:~/schedule;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE
spring.datasource.driverClassName=org.h2.Driver
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=always
spring.quartz.jdbc.commentPrefix=” — “
spring.quartz.properties.org.quartz.threadPool.threadCount=10
spring.quartz.properties.org.quartz.jobStore.isClustered=<b>true</b>
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=5000
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO

再次运行Spring启动应用程序,您将看到Quartz正在使用数据库H2来保持其作业,而Quartz正在以群集模式运行。

2019–03–18 15:14:44.628 INFO 30715 — — [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.0) ‘quartzScheduler’ with instanceId ‘q2256s-MacBook-Pro.local1552940084611’
Scheduler <b>class</b>: ‘org.quartz.core.QuartzScheduler’ — running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool ‘org.quartz.simpl.SimpleThreadPool’ — with 10 threads.
Using job-store ‘org.springframework.scheduling.quartz.LocalDataSourceJobStore’ — which supports persistence. and is clustered.

您同时运行两个实例,您将看到计划任务在两个实例之一随机执行。这是我机器上的结果:

*实例1

2019–03–18 19:34:26.162 INFO 45385 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552955666049 started.
2019–03–18 19:34:26.176 INFO 45385 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 21.606 seconds (JVM running <b>for</b> 22.139)
2019–03–18 19:35:00.024 INFO 45385 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:35:00
2019–03–18 19:37:00.015 INFO 45385 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:37:00

*实例2

2019–03–18 19:33:31.706 INFO 45308 — — [ main] o.s.s.quartz.SchedulerFactoryBean : Starting Quartz Scheduler now
2019–03–18 19:33:31.711 INFO 45308 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552955611600 started.
2019–03–18 19:33:31.732 INFO 45308 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 36.684 seconds (JVM running <b>for</b> 37.12)
2019–03–18 19:34:00.015 INFO 45308 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:34:00
2019–03–18 19:36:00.008 INFO 45308 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:36:00
2019–03–18 19:38:00.007 INFO 45308 — — [eduler_Worker-3] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:38:00

如果停止一个实例,当检测到失败的实例时,保留的实例每分钟运行一次:

2019–03–18 19:40:01.788 INFO 45308 — — [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore : ClusterManager: detected 1 failed or restarted instances.
2019–03–18 19:40:01.788 INFO 45308 — — [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore : ClusterManager: Scanning <b>for</b> instance “q2256s-MacBook-Pro.local1552955666049”’s failed in-progress jobs.
2019–03–18 19:41:00.010 INFO 45308 — — [eduler_Worker-5] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:41:00
2019–03–18 19:42:00.005 INFO 45308 — — [eduler_Worker-6] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:42:00
2019–03–18 19:43:00.004 INFO 45308 — — [eduler_Worker-7] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:43:00
2019–03–18 19:44:00.007 INFO 45308 — — [eduler_Worker-8] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:44:00

结论

我们刚刚在集群环境中构建了调度微服务。它对于复杂的企业项目尤其有用,因为您将为一些关键业务运行许多计划任务,例如计费,通知,电子邮件营销等,失败的服务可能会使您的业务停止运行。

完整的源代码位于 https://github.com/haiphucnguyen/Quartz-Demo上 ,您可以在IDE或控制台中导入并运行它。

原文  https://www.jdon.com/51922
正文到此结束
Loading...