SpringBoot整合Quartz實現(xiàn)定時任務(wù)詳解
Quartz簡介
Quartz 是一個開源的作業(yè)調(diào)度框架,它完全由 Java 寫成,并設(shè)計用于 J2SE 和 J2EE 應(yīng)用中。它提供了巨大的靈活性而不犧牲簡單性。你能夠用它來為執(zhí)行一個作業(yè)而創(chuàng)建簡單的或復(fù)雜的調(diào)度。它有很多特征,如:數(shù)據(jù)庫支持,集群,插件,EJB 作業(yè)預(yù)構(gòu)建,JavaMail 及其它,支持 cron-like 表達式等等。
核心概念
主要有三個核心概念:調(diào)度器、任務(wù)和觸發(fā)器。三者關(guān)系簡單來說就是,調(diào)度器負(fù)責(zé)調(diào)度各個任務(wù),到了某個時刻或者過了一定時間,觸發(fā)器觸動了,特定任務(wù)便啟動執(zhí)行。
Scheduler
Scheduler(調(diào)度器),基于trigger(觸發(fā)器)的設(shè)定執(zhí)行job(任務(wù)),代表一個Quartz的獨立運行容器,Trigger和JobDetail要注冊到Scheduler中才會生效,也就是讓調(diào)度器知道有哪些觸發(fā)器和任務(wù),才能進行按規(guī)則進行調(diào)度任務(wù)。
JobDetail
Quartz 中需要執(zhí)行的任務(wù)詳情,包括了任務(wù)的唯一標(biāo)識和具體要執(zhí)行的任務(wù),可以通過 JobDataMap 往任務(wù)中傳遞數(shù)據(jù)
Job
Job(任務(wù)),封裝成JobDetail設(shè)置屬性。
其中有兩個重要注解
@DisallowConcurrentExecution :禁止并發(fā)的執(zhí)行同一個job定義的多個實例
@PersistJobDataAfterExecution:持久化JobDetail中的JobDataMap(對trigger中的DataMap無效)
Trigger
Trigger(觸發(fā)器),描述觸發(fā)Job執(zhí)行的時間觸發(fā)規(guī)則。有SimpleTrigger和CronTrigger兩個子類代表兩種方式,一種是每隔多少分鐘小時執(zhí)行,則用SimpleTrigger;另一種是日歷相關(guān)的重復(fù)時間間隔,如每天凌晨,每周星期一運行的話,通過Cron表達式便可定義出復(fù)雜的調(diào)度方案。
SpringBoot整合Quartz
準(zhǔn)備數(shù)據(jù)庫表
不同版本的quartz使用的數(shù)據(jù)庫表不同,具體如下,選擇對應(yīng)版本即可
https://github.com/quartz-scheduler/quartz/tree/quartz-2.1.x
創(chuàng)建之后,表關(guān)系如圖所示
Maven相關(guān)依賴
<!--spring連接驅(qū)動時,如com.mysql.cj.jdbc.Driver使用--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--quartz依賴--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
配置文件
application.yml
spring: datasource: username: xxx password: xxxxxx url: jdbc:mysql://localhost:3306/qrtz_db?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver
spring-quartz.properties
#===================================================================
#配置JobStore
#===================================================================#JobDataMaps是否都為String類型,默認(rèn)為false
org.quartz.jobStore.useProperties = false#表前綴
org.quartz.jobStore.tablePrefix = qrtz_#是否加入集群
org.quartz.jobStore.isClustered = true#調(diào)度實例失敗的檢查時間間隔 ms
org.quartz.jobStore.clusterCheckinInterval = 5000org.quartz.jobStore.txIsolationLevelReadCommitted = true
#數(shù)據(jù)保存方式為數(shù)據(jù)持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX#數(shù)據(jù)庫代理類,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以滿足大部分?jǐn)?shù)據(jù)庫
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate#===================================================================
#配置Scheduler 調(diào)度器屬性配置
#===================================================================#調(diào)度標(biāo)識名 集群中每一個實例都必須使用相同的名稱
org.quartz.scheduler.instanceName = ClusterQuartz#ID設(shè)置為自動獲取 每一個必須不同
org.quartz.scheduler.instanceId = AUTO#===================================================================
#配置ThreadPool
#===================================================================#線程池的實現(xiàn)類(一般使用SimpleThreadPool即可滿足幾乎所有的用戶)
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool#指定線程數(shù),一般設(shè)定為1-100之間的整數(shù),根據(jù)系統(tǒng)資源配置
org.quartz.threadPool.threadCount = 5#設(shè)置線程的優(yōu)先級(可以是Thread.MIN_PRIORITY(即1)和Thread.MAX_PRIORITY(10)之間的任何int)
org.quartz.threadPool.threadPriority = 5
quartz配置類
@Configuration public class SchedulerConfig { @Autowired private DataSource dataSource; @Bean public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setSchedulerName("cluster_scheduler"); factory.setDataSource(dataSource); factory.setApplicationContextSchedulerContextKey("application"); factory.setQuartzProperties(quartzProperties()); factory.setTaskExecutor(schedulerThreadPool()); factory.setStartupDelay(10); return factory; } @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/spring-quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } @Bean public Executor schedulerThreadPool(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(8); executor.setMaxPoolSize(8); executor.setQueueCapacity(8); return executor; } }
創(chuàng)建任務(wù)類
@PersistJobDataAfterExecution @DisallowConcurrentExecution public class QuartzJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { try { Thread.sleep(2000); System.out.println(context.getScheduler().getSchedulerInstanceId()); System.out.println("taskName="+context.getJobDetail().getKey().getName()); System.out.println("執(zhí)行時間="+new Date()); } catch (Exception e) { e.printStackTrace(); } } }
創(chuàng)建監(jiān)聽類
@Component public class StartApplicationListener implements ApplicationListener<ContextRefreshedEvent> { @Autowired private Scheduler scheduler; @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { TriggerKey triggerKey = TriggerKey.triggerKey("trigger1","group1"); try { Trigger trigger = scheduler.getTrigger(triggerKey); if (trigger == null){ trigger = TriggerBuilder.newTrigger() .withIdentity(triggerKey) .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) .startNow() .build(); JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class) .withIdentity("job1","group1") .build(); scheduler.scheduleJob(jobDetail,trigger); scheduler.start(); } } catch (SchedulerException e) { e.printStackTrace(); } } }
運行結(jié)果
可以看到每隔十秒執(zhí)行一次。
到此這篇關(guān)于SpringBoot整合Quartz實現(xiàn)定時任務(wù)詳解的文章就介紹到這了,更多相關(guān)SpringBoot Quartz內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot 快速實現(xiàn) api 加密的方法
在項目中,為了保證數(shù)據(jù)的安全,我們常常會對傳遞的數(shù)據(jù)進行加密,常用的加密算法包括對稱加密(AES)和非對稱加密(RSA),本文給大家介紹SpringBoot 快速實現(xiàn) api 加密,感興趣的朋友一起看看吧2023-10-10Mybatis注解方式完成輸入?yún)?shù)為list的SQL語句拼接方式
這篇文章主要介紹了Mybatis注解方式完成輸入?yún)?shù)為list的SQL語句拼接方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11最新IDEA?2022基于JVM極致優(yōu)化?IDEA啟動速度的方法
這篇文章主要介紹了IDEA?2022最新版?基于?JVM極致優(yōu)化?IDEA?啟動速度,需要的朋友可以參考下2022-08-08