如何實現Spring Boot和Quartz整合? - Nguyen Phuc Hai
排程是企業應用程式中的關鍵服務。您需要安排計劃服務,比如向終端使用者傳送有關即將舉行的結算活動,通知或營銷活動的電子郵件通知。在Java世界中,Quartz是流行的開源排程庫,支援簡單或Cron觸發器。使用Spring boot和Quartz比直接使用內建的Spring schedule要有點複雜,
但是Quartz作業可以持久儲存在記憶體或資料庫中。Jobs的永續性使Quartz完美地適用於微服務架構和叢集環境,您可以在多個機器中安裝排程服務,並避免了標準的Spring schedule排程服務不提供與Quartz相同的強度的故障服務。
在本文中,您將學習如何在Spring啟動專案中執行Quart作業。您將排程專案配置為微服務(沒有Web元件),將作業持久儲存到資料庫並以群集模式執行。
獲取完整的示例程式碼https://github.com/haiphucnguyen/Quartz-Demo,解壓縮並匯入您喜歡的IDE或文字編輯器。
建立Spring啟動應用程式
開啟https://start.spring.io/ ,建立新專案`quartz-demo`。將依賴項`JDBC`,`H2`,`Quartz`新增到專案中。然後生成新專案。
解壓縮專案檔案並將其匯入IntelliJ專案。
建立計劃任務
我建立了僅記錄當前時間的簡單計劃任務:
@Component public class ScheduleTask extends QuartzJobBean { private static final Logger LOG = LoggerFactory.getLogger(ScheduleTask.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { LOG.info("The current time is: " + dateFormat.format(new Date())); } } |
Quartz作業細節說明
Quartz不管理這項工作,而是透過JobDetail來完成。如果需要,您可以新增說明或作業的預定義資料。
@Bean public JobDetail scheduleJob() { return JobBuilder.newJob(ScheduleTask.class).storeDurably() .withIdentity("sample_schedule").withDescription("Sample schedule task").build(); } |
告訴Quartz什麼時候執行你的作業
你需要在作業執行時告訴Quartz。Trigger類可以幫助您完成此操作。請注意,許多觸發器可以指向同一個作業,但是一個觸發器只有一個作業。您可以使用類TriggerBuilder來構造`Trigger`例項
@Bean public Trigger scheduleTrigger() { return newTrigger().withIdentity("trigger").forJob(scheduleJob()). withSchedule(CronScheduleBuilder.cronSchedule("0 * * * * ?")).build(); } |
將排程服務作為獨立應用程式執行
執行Spring啟動應用程式,它會在輸出中記錄時間。您可能會將此應用程式視為一個排程微服務,它將執行定義任務執行時間的規則中的任務。
@SpringBootApplication public class QuartzDemoApplication { public static void main(String[] args) { SpringApplication.run(QuartzDemoApplication.class, args); } } |
輸出如下:
2019–03–18 19:53:43.737 INFO 46613 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552956823635 started. 2019–03–18 19:53:43.752 INFO 46613 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 36.769 seconds (JVM running for 37.167) 2019–03–18 19:54:00.017 INFO 46613 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:54:00 2019–03–18 19:55:00.010 INFO 46613 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:55:00 |
將Quartz作業保留到群集環境中的資料庫
想象一下,你有排程微服務,並且你想讓它執行叢集環境,如果機器主機一個排程服務停機並且不使整個排程服務停止執行。在此示例中,我將Quartz配置為在群集模式下將其作業保留在H2資料庫中。在`application.properties`檔案中宣告資料來源和Quartz設定
spring.datasource.url=jdbc:h2:~/schedule;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE spring.datasource.driverClassName=org.h2.Driver spring.quartz.job-store-type=jdbc spring.quartz.jdbc.initialize-schema=always spring.quartz.jdbc.commentPrefix=” — “ spring.quartz.properties.org.quartz.threadPool.threadCount=10 spring.quartz.properties.org.quartz.jobStore.isClustered=true spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=5000 spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO |
再次執行Spring啟動應用程式,您將看到Quartz正在使用資料庫H2來保持其作業,而Quartz正在以群集模式執行。
2019–03–18 15:14:44.628 INFO 30715 — — [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.0) ‘quartzScheduler’ with instanceId ‘q2256s-MacBook-Pro.local1552940084611’ Scheduler class: ‘org.quartz.core.QuartzScheduler’ — running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool ‘org.quartz.simpl.SimpleThreadPool’ — with 10 threads. Using job-store ‘org.springframework.scheduling.quartz.LocalDataSourceJobStore’ — which supports persistence. and is clustered. |
您同時執行兩個例項,您將看到計劃任務在兩個例項之一隨機執行。這是我機器上的結果:
*例項1
2019–03–18 19:34:26.162 INFO 45385 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552955666049 started. 2019–03–18 19:34:26.176 INFO 45385 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 21.606 seconds (JVM running for 22.139) 2019–03–18 19:35:00.024 INFO 45385 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:35:00 2019–03–18 19:37:00.015 INFO 45385 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:37:00 |
*例項2
2019–03–18 19:33:31.706 INFO 45308 — — [ main] o.s.s.quartz.SchedulerFactoryBean : Starting Quartz Scheduler now 2019–03–18 19:33:31.711 INFO 45308 — — [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_q2256s-MacBook-Pro.local1552955611600 started. 2019–03–18 19:33:31.732 INFO 45308 — — [ main] c.s.quartzdemo.QuartzDemoApplication : Started QuartzDemoApplication in 36.684 seconds (JVM running for 37.12) 2019–03–18 19:34:00.015 INFO 45308 — — [eduler_Worker-1] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:34:00 2019–03–18 19:36:00.008 INFO 45308 — — [eduler_Worker-2] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:36:00 2019–03–18 19:38:00.007 INFO 45308 — — [eduler_Worker-3] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:38:00 |
如果停止一個例項,當檢測到失敗的例項時,保留的例項每分鐘執行一次:
2019–03–18 19:40:01.788 INFO 45308 — — [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore : ClusterManager: detected 1 failed or restarted instances. 2019–03–18 19:40:01.788 INFO 45308 — — [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore : ClusterManager: Scanning for instance “q2256s-MacBook-Pro.local1552955666049”’s failed in-progress jobs. 2019–03–18 19:41:00.010 INFO 45308 — — [eduler_Worker-5] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:41:00 2019–03–18 19:42:00.005 INFO 45308 — — [eduler_Worker-6] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:42:00 2019–03–18 19:43:00.004 INFO 45308 — — [eduler_Worker-7] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:43:00 2019–03–18 19:44:00.007 INFO 45308 — — [eduler_Worker-8] com.schedule.quartzdemo.ScheduleTask : The current time is: 19:44:00 |
結論
我們剛剛在叢集環境中構建了排程微服務。它對於複雜的企業專案尤其有用,因為您將為一些關鍵業務執行許多計劃任務,例如計費,通知,電子郵件營銷等,失敗的服務可能會使您的業務停止執行。
完整的原始碼位於https://github.com/haiphucnguyen/Quartz-Demo上,您可以在IDE或控制檯中匯入並執行它。
相關文章
- Quartz - Spring和Quartz的整合quartzSpring
- Quartz - Spring整合Quartz實現叢集的定時任務quartzSpring
- 如何在Spring Boot中實現整合測試?Spring Boot
- Spring Boot整合MyBatis實現通用MapperSpring BootMyBatisAPP
- spring-quartz整合Springquartz
- Spring Boot整合quartz實現定時任務並支援切換任務資料來源Spring Bootquartz
- Spring Boot Quartz 分散式叢集任務排程實現Spring Bootquartz分散式
- Spring Boot 整合 MyBatis和 SQL Server實踐Spring BootMyBatisSQLServer
- Spring Boot整合Spring Cloud Task實現批處理操作Spring BootCloud
- Spring Boot 入門(六):整合 treetable 和 zTree 實現樹形圖Spring Boot
- Spring Boot整合Hystrix實現服務容錯Spring Boot
- Spring Boot 整合 Elasticsearch 實戰Spring BootElasticsearch
- Spring Boot 參考指南(Quartz Scheduler)Spring Bootquartz
- spring boot使用Jedis整合Redis實現快取(AOP)Spring BootRedis快取
- 使用Spring Boot實現資料庫整合配置案例Spring Boot資料庫
- Spring Boot 整合 Flyway 實現資料庫版本控制Spring Boot資料庫
- Spring Boot 如何快速整合 Redis 哨兵?Spring BootRedis
- spring-boot-route(二十一)quartz實現動態定時任務Springbootquartz
- 如何實現自己的Spring Boot StarterSpring Boot
- Spring Boot整合Redis實戰操作Spring BootRedis
- 如何使用Spring Boot,Spring Data和H2 DB實現REST APISpring BootRESTAPI
- Spring Boot 配置 Quartz 定時任務Spring Bootquartz
- Spring Boot整合Spring SecuritySpring Boot
- Spring Boot整合Spring BatchSpring BootBAT
- Spring Boot整合Spring AopSpring Boot
- Spring Boot整合Postgres實現輕量級全文搜尋Spring Boot
- Spring Boot 整合 Shiro實現認證及授權管理Spring Boot
- Spring Boot 整合 Sa-Token 實現登入認證Spring Boot
- Spring Boot系列十九 Spring boot整合 swaggerSpring BootSwagger
- Spring Boot 2.0(八):Spring Boot 整合 MemcachedSpring Boot
- 七、Spring Boot整合Spring Security之前後分離認證最佳實現Spring Boot
- Spring boot入門(二):Spring boot整合MySql,Mybatis和PageHelper外掛Spring BootMySqlMyBatis
- 使用Spring Boot和Kafka Streams實現CQRSSpring BootKafka
- Spring Boot 和 Thymeleaf 實現 Java 版 HTMXSpring BootJava
- spring boot整合jooqSpring Boot
- Spring Boot整合SocketSpring Boot
- Spring Boot整合rabbitmqSpring BootMQ
- Spring Boot整合RedisSpring BootRedis