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

Quartz 任務調度進階:封裝 JobWrapper 實現狀態管理、異常處理與依賴控制

     編輯:Java 相關知識

Quartz 基礎回顧

  • Job 實作 execute(JobExecutionContext)
  • Trigger 定義時間策略(CronTrigger 最常用)
  • Scheduler 綁定 JobDetail 與 Trigger
  • JobDataMap 傳遞參數

業務痛點

原生 Quartz 缺乏:任務運行狀態查看、歷史記錄、異常告警/重試、任務依賴排程。

解決方案:Annotation + JobWrapper 模式

1. 以 Annotation 定義任務入口


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Run { }

public class SimpleJob {
    @Run
    public void doit() { Thread.sleep(20000); }
}

2. 統一入口 JobWrapper


public class JobWrapper implements Job {
    private String id;
    private BatchDescription desc;
    private Object realJob;
    private Method runMethod;

    public JobWrapper() {
        id = System.currentTimeMillis() + "_" + Thread.currentThread().getId();
        stateChanged(id, JobStatus.INIT);
        JobManager.instance().reg(this);
    }

    public void execute(JobExecutionContext context) throws JobExecutionException {
        desc = (BatchDescription) context.getJobDetail().getJobDataMap().get("JobData");
        try {
            realJob = Class.forName(desc.getClassName()).newInstance();
            runMethod = getRunMethod(); // 掃描 @Run 註解方法
            stateChanged(id, JobStatus.RUNNING);
            runMethod.invoke(realJob, desc.getParamenter());
            stateChanged(id, JobStatus.SUCCESS);
        } catch (InvocationTargetException e) {
            stateChanged(id, JobStatus.EXCEPTION, e.getTargetException().getMessage());
        } catch (Exception e) {
            stateChanged(id, JobStatus.EXCEPTION, e.getMessage());
        }
    }

    private Method getRunMethod() { ... } // 反射查找 @Run 方法
    private void stateChanged(String id, JobStatus status, String msg) {
        JobDao.save(id, desc.getClassName(), status, msg, new Date()); // 持久化狀態
    }
}

3. 排程啟動範例


BatchDescription bd = new BatchDescription("com.demo.SimpleJob", "0 6 * * *", null);
JobDetail job = new JobDetail(bd.getClassName() + ".Job", "group", JobWrapper.class);
job.getJobDataMap().put("JobData", bd);
CronTrigger trigger = new CronTrigger(bd.getClassName() + ".Trigger");
trigger.setCronExpression(new CronExpression(bd.getCron()));
scheduler.scheduleJob(job, trigger);

擴展方向

  • 依賴控制:JobManager 維護 DAG,stateChanged 觸發下游任務。
  • 異常重試:狀態為 EXCEPTION 時,啟動重試策略(指數退避、最大次數)。
  • 管理控制台:讀取 JobDao 記錄,提供 Web 介面查看、手動觸發、暫停/恢復。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved