相比于scheduler,quartz支持分布式、持久化。当你部署多个实例时,定时任务会在多个实例上调度执行,提升了处理能力,同时多个实例也不会重复执行同一任务。而且也保证了服务的可靠性和高可用。
依赖
implementation("org.springframework.boot:spring-boot-starter-quartz")
现在我都用gradle进行依赖管理,比maven简洁和智能。
gradle后台使用的也是maven源。
配置
application.yml
spring:
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
由于配置了job-store-type: jdbc
,我们需要有一个数据源,比如mysql:
spring:
datasource:
url: jdbc:mysql://192.168.1.11:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: xxxxx
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 5
idle-timeout: 180000
maximum-pool-size: 10
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: select 1
和平时的datasource是一致的。
定时任务代码
注解配置trigger
代码是用kotlin写的:
@Configuration
class QuartzSchedulerConfig {
@Bean
fun jobTrigger(jobDetail:JobDetail):CronTriggerFactoryBean{
val trigger = CronTriggerFactoryBean()
trigger.setJobDetail(jobDetail)
trigger.setCronExpression("0/15 * * * * ?")
return trigger
}
@Bean
fun jobDetail():JobDetailFactoryBean{
val jobDetailFactoryBean = JobDetailFactoryBean()
jobDetailFactoryBean.setJobClass(WeatherJob::class.java)
jobDetailFactoryBean.setDurability(true)
return jobDetailFactoryBean
}
}
任务代码
@Component
class WeatherJob : QuartzJobBean() {
private val log:Logger = LoggerFactory.getLogger(WeatherJob::class.java)
/**
* Execute the actual job. The job data map will already have been
* applied as bean property values by execute. The contract is
* exactly the same as for the standard Quartz execute method.
* @see .execute
*/
override fun executeInternal(context: JobExecutionContext) {
log.info("start job")
}
}
每15秒会调用上面的executeInternal
方法。
完成!