作業排程是現代系統的基本需求。Quartz 作為開源排程框架,提供簡單卻強大的機制:支援按時間間隔或行事曆排程、實作作業與觸發器多對多關聯、可重用作業並組合多個作業於單一事件。雖可透過屬性檔配置(資料源、監聽器、外掛、執行緒池等),但不與應用伺服器上下文整合,排程作業無法存取伺服器內部功能(如動態快取、資料源)。
Quartz 兩大基本單元:
org.quartz.Job 介面將工作內容與排程分離,允許不變更作業即修改排程,且單一作業可關聯多個觸發器。
public class SimpleQuartzJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("執行時間:" + new Date() + " 觸發器:" + context.getTrigger().getName());
}
}
JobExecutionContext 提供執行時上下文(排程器、觸發器、JobDetail)。JobDetail 儲存作業狀態(監聽器、群組、資料映射、描述等),構造函數啟動作業實例,實現執行與狀態分離。
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
JobDetail jobDetail = new JobDetail("job1", "group1", SimpleQuartzJob.class);
SimpleTrigger trigger = new SimpleTrigger("trigger1", "group1");
trigger.setStartTime(new Date()); // 立即啟動
trigger.setRepeatInterval(10000); // 每 10 秒
trigger.setRepeatCount(100); // 執行 100 次
// trigger.setEndTime(new Date(ctime + 60000)); // 或設定結束時間
// trigger.setPriority(10); // 優先級(預設 5)
sched.scheduleJob(jobDetail, trigger);
sched.start();
除重複次數/間隔,可指定行事曆時間、最長執行時間、優先級。最長執行時間可覆蓋重複次數。
基於 Cron 運算式(7 欄位:秒、分、時、日、月、週、年(可選)),支援複雜排程。特殊字元:
/ 遞增(如 5/15 表示第 5 秒起每 15 秒)? 無指定值(用於日/週互斥欄位)L 最後(月最後一天、週最後一天)W 工作日(最接近指定日的工作日)# 第 N 個工作日(如 MON#2 當月第二個週一)* 萬用字元CronTrigger cronTrigger = new CronTrigger("cronTrigger", "group2");
CronExpression cexp = new CronExpression("0/5 * * * * ?"); // 每 5 秒
cronTrigger.setCronExpression(cexp);
sched.scheduleJob(jobDetail, cronTrigger);
sched.start();
Quartz 提供兩種作業倉儲:
| 類型 | 特點 |
|---|---|
| RAMJobStore(預設) | 資料存在記憶體,效能最佳,但缺乏持久性,崩潰會遺失資料 |
| JDBCJobStore | 資料存資料庫,持久可靠,但效能較低、設定較複雜 |
docs/dbTables 目錄),支援主流資料庫quartz.properties 關鍵屬性:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = qzDS
org.quartz.dataSource.qzDS.driver = com.ibm.db2.jcc.DB2Driver
org.quartz.dataSource.qzDS.URL = jdbc:db2://localhost:50000/QZ_SMPL
org.quartz.dataSource.qzDS.user = db2inst1
org.quartz.dataSource.qzDS.password = pass4dbadmin
org.quartz.dataSource.qzDS.maxConnections = 30
啟動應用 → 觸發器在資料庫初始化(REPEAT_COUNT=100, TIMES_TRIGGERED=0) → 執行一段時間停止(TIMES_TRIGGERED=19) → 重新啟動(REPEAT_COUNT 自動更新為 81=100-19,TIMES_TRIGGERED 從 0 重新計數) → 再次停止(REPEAT_COUNT 再更新)。

完整 quartz.properties 範例:
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
# RAMJobStore 設定(預設)
# org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
# JDBCJobStore 設定
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = qzDS
org.quartz.dataSource.qzDS.driver = com.ibm.db2.jcc.DB2Driver
org.quartz.dataSource.qzDS.URL = jdbc:db2://localhost:50000/dbname
org.quartz.dataSource.qzDS.user = dbuserid
org.quartz.dataSource.qzDS.password = password
org.quartz.dataSource.qzDS.maxConnections = 30
Quartz API 兼具全面強大與易用性:從簡單觸發到複雜 JDBC 持久排程皆能輕鬆應對。OpenSymphony 成功填補開源領域空白,讓曾經繁瑣的作業排程成為開發人員的小菜一碟。