springboot + quartz
添加依赖
<!-- quartz依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
application.yml 配置
- 博客配置详解:
- 官网文档:
https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-quartz
spring:
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler // 集群配置
instanceId: AUTO // 集群配置
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX // 数据库方式保存, 内存方式保存为: org.quartz.simpl.RAMJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate // 所有JDBC兼容的驱动
tablePrefix: QRTZ_ //表前缀,默认配置, 不需要修改
isClustered: true // 是否集群状态
clusterCheckinInterval: 10000 //
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool // 线程池类型
threadCount: 10 // 连接数
threadPriority: 5 // 线程优先级
threadsInheritContextClassLoaderOfInitializingThread: true // 是否自创建父线程
#数据库方式
job-store-type: jdbc // 数据库方式
#初始化表结构
#jdbc:
#initialize-schema: never // 这个在官方文档上面详细介绍了
数据库脚本
> 脚本位置在, org.quartz-scheduler 这个包下, 路径: org.quartz.impl.jdbcjobstore, 选择自己的
脚本在应用的datasource对应的数据库执行一下, 如果需要隔离, 则需要为quartz单独配置数据源
集群状态下, 任务并发, 持久化问题,两个注解
在某些集群任务执行过程中,你会发现一个任务同时被集群中两台机器触发了,这在生产环境中是非常严重的问题,
添加@DisallowConcurrentExecution 大概率可以解决问题
//持久化
@PersistJobDataAfterExecution
//禁止并发执行(Quartz不要并发地执行同一个job定义(这里指一个job类的多个实例))
@DisallowConcurrentExecution
@Slf4j
public class QuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.info("quartz job execute, date: ", new Date());
}
}
关于任务类是否可以注入spring bean 的问题
> springboot 整合 quartz 后, 使用RAM的方式是天生支持任务类中注入spring对象的. 所以直接像在controller里面用
service 一样注入就可以了, 持久化方式的bean注入, 下面会持续更新
quartz config 配置
@Configuration
public class QuartzConfiguration {
@Value("${cron.expression}")
private String cronExpression;
@Bean
public JobDetail myCronJobDetail() {
return JobBuilder.newJob(EntranceJob.class).withIdentity("entranceJob").storeDurably().build();
}
@Bean
public Trigger CronJobTrigger() {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
return TriggerBuilder.newTrigger()
.forJob(myCronJobDetail())
.withIdentity("entranceJobTrigger")
.withSchedule(cronScheduleBuilder)
.build();
}
}
例子:
@Component
@PersistJobDataAfterExecution // 持久化
@DisallowConcurrentExecution // 不并发执行
public class EntranceJob extends QuartzJobBean {
@Autowired
CarWeightInfoServicePlug carWeightInfoServicePlug;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(carWeightInfoServicePlug);
System.err.println("定时任务执行了.......");
}
}
如果需要任务持久化, 或者是集群部署的话,需要建表, 把依赖的11张表从jar包中找出来, 创建后修改配置, 同一个集群的数据源要一样, instanceName 一样就可以了