首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Web 任務調度深度解析:Quartz + Struts Plugin 整合實戰、叢集模式與現代替代方案

     編輯:Java 程式設計入門

為什麼需要任務調度?

  • 非即時處理:報表產生、資料同步、郵件發送、快取預熱、資料清理。
  • 固定排程:每日 02:00 執行、每小時、每週一、Cron 表達式彈性排程。
  • 避免使用者等待:前端觸發後台非同步任務,輪詢/WebSocket 推送結果。

Quartz 核心概念

概念說明
Job任務介面,實作 execute(JobExecutionContext)
JobDetail任務定義:名稱、群組、實作類別、持久化資料
Trigger觸發條件:SimpleTrigger(固定間隔)、CronTrigger(Cron 表達式)
Scheduler核心調度器,管理 Job/Trigger 生命週期、啟動/暫停/叢集
JobStore持久化策略:RAMJobStore(記憶體)、JDBCJobStore(資料庫、支援叢集)

Web 容器啟動自動啟動 Scheduler:Struts PlugIn 模式

struts-config.xml 註冊

<plug-in className="com.example.SchedulerPlugIn">
  <set-property property="startOnLoad" value="true" />
  <set-property property="startupDelay" value="5000" /> <!-- 延遲 5 秒,等資料源就緒 -->
</plug-in>

SchedulerPlugIn 實作

public class SchedulerPlugIn implements PlugIn {
    private Scheduler scheduler;
    private boolean startOnLoad = true;
    private long startupDelay = 0;

    public void setStartOnLoad(boolean b) { this.startOnLoad = b; }
    public void setStartupDelay(long ms) { this.startupDelay = ms; }

    @Override
    public void init(ActionServlet servlet, ModuleConfig config) {
        ServletContext ctx = servlet.getServletContext();
        StdSchedulerFactory factory = (StdSchedulerFactory) 
            ctx.getAttribute(QuartzInitializerServlet.QUARTZ_FACTORY_KEY);
        try {
            scheduler = factory.getScheduler();
            if (startOnLoad) {
                Thread.sleep(startupDelay);
                scheduler.start();
            }
        } catch (Exception e) { throw new RuntimeException(e); }
    }

    @Override
    public void destroy() {
        try { scheduler.shutdown(true); } catch (SchedulerException ignore) {}
    }
}

QuartzInitializerServlet 於 web.xml 註冊(提供 StdSchedulerFactory)

<servlet>
  <servlet-name>QuartzInitializer</servlet-name>
  <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
  <init-param>
    <param-name>config-file</param-name>
    <param-value>/WEB-INF/quartz.properties</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

定義 Job 與排程(程式碼式)

public class ReportJob implements Job {
    @Override
    public void execute(JobExecutionContext ctx) {
        // 產生報表、寄送 Email...
    }
}

// 在 ServletContextListener 或 PlugIn 中排程
JobDetail job = JobBuilder.newJob(ReportJob.class)
    .withIdentity("reportJob", "reportGroup")
    .build();

Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity("reportTrigger", "reportGroup")
    .withSchedule(CronScheduleBuilder.cronSchedule("0 0 2 * * ?")) // 每日 02:00
    .build();

scheduler.scheduleJob(job, trigger);

叢集模式關鍵設定(quartz.properties)

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.dataSource.myDS.jndiURL = java:comp/env/jdbc/quartzDS
  • 所有節點共用同一組資料庫表。
  • isClustered=true 啟用分散式鎖、負載均衡、故障轉移。
  • 需建立 Quartz 官方提供的建表腳本(tables_.sql)。

現代替代方案對比

方案優點缺點適用場景
Spring @Scheduled零配置、原生整合、支援 Cron/固定延遲單機、無持久化、無叢集、無動態管理簡單定時任務、微服務單節點
Spring Batch大量資料處理、分塊、重試、重啟、監控非通用排程、學習曲線高ETL、報表、資料遷移
Quartz功能完整、叢集、持久化、動態管理、JTA 事務配置複雜、API 老舊企業級排程、需叢集/持久化
xxl-job分散式、Web 控制台、動態分片、失敗重試、多語言需部署調度中心、Java 生態外較弱跨語言、可視化運維、大規模分散式
PowerJob阿里開源、高效能、工作流、資料列血緣社群較新複雜任務編排、資料治理

最佳實務清單

  1. Job 類別實作 Serializable(叢集必備)。
  2. Job 內捕獲所有異常,記錄日誌,避免觸發器誤以為成功。
  3. 冪等性設計:同一任務重複執行不產生副作用(資料庫唯一鍵、狀態機)。
  4. 監控指標:任務執行時間、成功率、佇列堆積、執行緒池使用率。
  5. 優雅關閉:scheduler.shutdown(true) 等待執行中任務完成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved