SpringBoot
2.0 開始官方提供了對quartz
定時任務的自動配置支持依賴spring-boot-starter-quartz
組件,無需自行集成java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
複製代碼
環境版本:mysql
在pom.xml中添加quartz、Jpa、mysql驅動、lombok依賴spring
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
複製代碼
添加數據庫配置sql
spring:
datasource:
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: hmdt
url: jdbc:mysql://db/bussines_db?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
quartz:
url: jdbc:mysql://db/bussines_quartz?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: hmdt
quartz:
#相關屬性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
# 數據源名稱
dataSource: quartzDataSource
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 1000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
job-store-type: jdbc
#初始化表結構
jdbc:
initialize-schema: never
jpa:
hibernate:
ddl-auto: update
show-sql: true
database-platform: org.hibernate.dialect.MySQL55Dialect
properties:
hibernate:
format_sql: true
use_sql_comments: true
複製代碼
數據庫配置也有樣例配在spring.quartz.properties
中,但親測配置無效,而且因爲還須要指定鏈接池等信息,此處配置在spring的鏈接池中更容易管理數據庫
儘管使用了JPA
,但因爲沒有實體關聯,spring
並不會幫咱們自動建表,還須要去官網下載sql
腳本併發
quartz官網dom
官網壓縮包路徑quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore
中支持大量數據庫建表語句,選擇對應的使用便可分佈式
多配置源以前在文章中詳細說過配置樣例和緣由,這裏再也不贅述ide
SpringBoot2.x Data JPA 多數據源爬坑spring-boot
編寫數據庫配置,統一使用HikariCP
鏈接池
package com.gcb.invest.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/** * 定時任務數據源配置 * * @author F嘉陽 * @date 2019-07-28 21:52 */
@Configuration
public class DataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.primary")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.primary.configuration")
public HikariDataSource firstDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("spring.datasource.quartz")
public DataSourceProperties quartzDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@QuartzDataSource
@ConfigurationProperties("spring.datasource.quartz.configuration")
public HikariDataSource quartzDataSource() {
return quartzDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
}
複製代碼
編寫定時任務,因爲通過Spring的封裝,使用變得更加方便
此處經過內部類配置定時任務,並使用@DisallowConcurrentExecution
註解指定其在分佈式環境下不可併發執行
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.QuartzJobBean;
/** * 定時任務配置 * * @author :F嘉陽 * @date :2019/7/29 9:16 */
@Slf4j
@Configuration
public class QuartzConfig {
/** * 測試定時任務構建 * * @return */
@Bean
public JobDetail testTaskJobDetail() {
return JobBuilder.newJob(TestTask.class)
.withIdentity(TestTask.class.getName())
.storeDurably(true)
.build();
}
/** * 測試定時任務配置 * * @return */
@Bean
public Trigger testTaskTrigger() {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(testTaskJobDetail())
.withIdentity(TestTask.class.getName())
.withSchedule(scheduleBuilder)
.build();
}
@DisallowConcurrentExecution
private class TestTask extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.debug("執行測試定時任務");
}
}
}
複製代碼
另外一種方式可以使用注入調度器手動構建任務,不過須要調用該方法以後調度器纔會被建立
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
/** * @author :F嘉陽 * @date :2019/7/29 8:59 */
@Service
@Transactional(rollbackFor = Exception.class)
public class QuartzTimerService {
@Autowired
private Scheduler scheduler;
public void buildGoodStockTimer() throws Exception {
//任務名稱
String name = UUID.randomUUID().toString();
//任務所屬分組
String group = CustomQuartzJob.class.getName();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
//建立任務
JobDetail jobDetail = JobBuilder.newJob(CustomQuartzJob.class).withIdentity(name,group).build();
//建立任務觸發器
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).withSchedule(scheduleBuilder).build();
//將觸發器與任務綁定到調度器內
scheduler.scheduleJob(jobDetail, trigger);
}
}
複製代碼
定時任務類
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
/** * @author :F嘉陽 * @date :2019/7/29 8:55 */
@Slf4j
@DisallowConcurrentExecution
public class CustomQuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info("執行定時任務");
}
}
複製代碼
執行成功
在分佈式環境下自動進行做業節點遷移