【springboot學習】spring整合quartz數據源

使用場景:

1.如果使用內存保存定時信息,一旦服務器宕機,那麼定時信息全部丟失,定時任務無法恢復,而使用數據庫保存定時任務信息,能夠在服務器重啓後,恢復原來定時任務的狀態,繼續執行。

2.在集羣環境下,多個服務器同時啓動定時任務,會出現任務的多次重複執行,這就需要集羣環境下,某一時刻只有一臺服務器執行定時任務,當主服務器宕機後,從服務器能夠接力執行定時任務。

quartz的數據庫方案,可以很好的滿足上面的兩種情景。

SQL文件下載

表結構創建語句可以在quartz官網下載
在這裏插入圖片描述
下載完成之後解壓,在docs\dbTables目錄下有各種版本的sql文件,這裏我用的是tables_mysql_innodb.sql適用於mysqlinnodb版本

表結構說明

調度器:存儲少量有關調度器的狀態信息。

存儲各種觸發器,觸發器觸發的記錄,觸發器組的暫停信息。

序號 表名 說明
1. qrtz_job_details 存儲每一個已配置的 Job 的詳細信息(jobDetail)
2. qrtz_triggers 存儲已配置的 觸發器 (Trigger) 的信息
3. qrtz_fired_triggers 存儲與已觸發的 Trigger 相關的狀態信息,以及相聯 Job 的執行信息
4. qrtz_cron_triggers 存儲 Cron Trigger,包括 Cron 表達式和時區信息
5. qrtz_simple_triggers 存儲簡單的 Trigger,包括重複次數,間隔,以及已觸的次數
6. qrtz_blog_triggers 以 Blob 類型存儲的Trigger
7. qrtz_scheduler_state 調度器狀態。
8. qrtz_locks 存儲程序的悲觀鎖的信息(假如使用了悲觀鎖)。
9. qrtz_calendars 以 Blob 類型存儲 Quartz 的 Calendar 信息

注意:cron方式需要用到的4張數據表: qrtz_triggersqrtz_cron_triggersqrtz_fired_triggersqrtz_job_details

配置文件

#==============================================================  
#配置調度器配置
#==============================================================   
#在同一個程序中,使用該名稱來區分scheduler,如果是集羣環境,必須使用同一個名稱,表示邏輯相同的Scheduler
org.quartz.scheduler.instanceName = MyScheduler 
#在集羣環境下,instanceId必須唯一,即使是邏輯相同的Scheduler,一般設爲AUTO
org.quartz.scheduler.instanceId = AUTO  

#==============================================================  
#線程池配置,
#============================================================== 
#必須配置,線程池實現的類名,Quartz附帶的線程池是“org.quartz.simpl.SimpleThreadPool”,並且應該能夠滿足幾乎每個用戶的需求。它有非常簡單的行爲,並經過很好的測試。它提供了一個固定大小的線程池,
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#必須配置,線程數
org.quartz.threadPool.threadCount = 10
#線程優先級,默認是5
org.quartz.threadPool.threadPriority = 5

#==============================================================  
#JobStore配置
#============================================================== 
#RAMJobStore(基於內存)和JDBCJobStore用於在關係數據庫中存儲調度信息
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#必須配置,代表瞭解不同數據庫系統的特定“方言”。StdJDBCDelegate(用於完全符合JDBC的驅動程序)
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#數據庫表名的前綴,支持自定義
org.quartz.jobStore.tablePrefix = QRTZ_
#在被認爲“失火”之前,調度程序將“容忍”一個Triggers將其下一個啓動時間通過的毫秒數
org.quartz.jobStore.misfireThreshold = 60000
#在給定的通行證中,工作區將處理的最大錯誤次數觸發。
org.quartz.jobStore.maxMisfiresToHandleAtATime=10
#設置爲“true”以打開羣集功能
org.quartz.jobStore.isClustered = true  
# 檢測羣集中的其他實例的頻率(以毫秒爲單位)。
org.quartz.jobStore.clusterCheckinInterval = 20000
# 此屬性的值必須是配置屬性文件中定義的DataSource的名稱
org.quartz.jobStore.dataSource = myDS

#配置數據源
#數據庫中quartz表的表名前綴
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/school?serverTimezone=GMT&characterEncoding=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 5

spring集成quartz

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.study.FirstSpringBoot.service.PrintTask;
import com.study.FirstSpringBoot.service.PrintTask2;

@Configuration
public class QuartzConfig {

	@Bean
	public SchedulerFactoryBean schedulerFactoryBean() {
		SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
		// 註冊定時觸發器
		schedulerFactoryBean.setTriggers(cronTriggerFactoryBean1().getObject(), cronTriggerFactoryBean2().getObject());
		// QuartzScheduler 啓動時更新己存在的Job,這樣就不用每次修改targetObject後刪除qrtz_job_details表對應記錄了
		schedulerFactoryBean.setOverwriteExistingJobs(true);
		// QuartzScheduler 延時啓動,應用啓動完後 QuartzScheduler 再啓動
		schedulerFactoryBean.setStartupDelay(1);
		// 設置加載的配置文件
		schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
		return schedulerFactoryBean;
	}

	@Bean
	public CronTriggerFactoryBean cronTriggerFactoryBean1() {
		CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
		// 定時觸發器綁定任務
		cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean1().getObject());
		cronTriggerFactoryBean.setCronExpression("0/30 * * * * ?");
		cronTriggerFactoryBean.setGroup("TiggerGroup1");
		return cronTriggerFactoryBean;
	}

	@Bean
	public JobDetailFactoryBean jobDetailFactoryBean1() {
		JobDetailFactoryBean factory = new JobDetailFactoryBean();
		factory.setGroup("JobGroup1");
		factory.setJobClass(PrintTask.class);
		factory.setDurability(true);
		return factory;
	}

	@Bean
	public CronTriggerFactoryBean cronTriggerFactoryBean2() {
		CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
		// 定時觸發器綁定任務
		cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean2().getObject());
		cronTriggerFactoryBean.setCronExpression("0 0/1 * * * ?");
		cronTriggerFactoryBean.setGroup("TiggerGroup2");
		return cronTriggerFactoryBean;
	}

	@Bean
	public JobDetailFactoryBean jobDetailFactoryBean2() {
		JobDetailFactoryBean factory = new JobDetailFactoryBean();
		factory.setGroup("JobGroup2");
		factory.setJobClass(PrintTask2.class);
		// 該屬性必須爲true,否則報錯 'Jobs added with no trigger must be durable'
		factory.setDurability(true);
		return factory;
	}
}

上面配置了兩個任務,第一個任務每隔30秒輸出print1111111,第二個任務每隔1分鐘輸出print2222222

public class PrintTask extends QuartzJobBean {

	private Logger log = LoggerFactory.getLogger(PrintTask.class);

	@Override
	protected void executeInternal(final JobExecutionContext context) throws JobExecutionException {

		log.info("print1111111");
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章