You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监控Quartz Scheduler中各cron任务的单批次运行失败情况

Quartz Scheduler 单任务运行状态监控实现方案

方案1:内置JobListener监听器实现(无额外依赖,原生支持)

  • 实现JobListener接口,重写3个核心方法:jobToBeExecuted(任务执行前触发)、jobWasExecuted(任务执行完成后触发,无论成功失败都会触发)、jobExecutionVetoed(任务被拦截未执行时触发)
  • 在jobWasExecuted方法中通过JobExecutionException参数判断执行结果:如果该对象不为空,说明本次批次运行抛出异常,可直接获取对应任务的身份标识、执行时间、异常堆栈等信息
  • 给每个独立cron任务绑定专属监听器,绑定时指定任务的JobKey或者JobGroup,避免监听器监听所有无关任务
  • 参考代码实现:
public class SingleJobMonitorListener implements JobListener {
    @Override
    public String getName() {
        return "SingleJobMonitorListener";
    }
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        // 记录任务启动日志,生成唯一批次ID、保存触发时间、任务Key等信息
        JobKey jobKey = context.getJobDetail().getKey();
        Long batchId = System.currentTimeMillis();
        context.put("batchId", batchId);
    }
    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        JobKey jobKey = context.getJobDetail().getKey();
        Long batchId = (Long) context.get("batchId");
        if (jobException != null) {
            // 此处处理失败逻辑:数据落库/触发告警/上报监控指标
            System.out.printf("任务[%s]批次[%d]执行失败,异常信息:%s%n", 
                jobKey, batchId, jobException.getMessage());
        } else {
            // 记录执行成功的状态
        }
    }
    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        // 处理任务被拦截未执行的场景
    }
}
  • 监听器绑定代码:
    scheduler.getListenerManager().addJobListener(new SingleJobMonitorListener(), KeyMatcher.keyEquals(new JobKey("你的任务名", "你的任务组")));
    可按单个任务绑定,也可按任务组批量绑定。

方案2:任务逻辑内嵌埋点(灵活度最高,可控性强)

  • 每个任务的execute方法外层用try-catch包裹所有业务逻辑
  • 进入方法时生成唯一批次号,记录任务启动时间、入参等基础信息
  • catch块中捕获所有Exception甚至Throwable,记录本次批次的失败原因、异常堆栈,同时可触发告警逻辑(邮件/钉钉/企业微信通知)
  • 注意不要吞异常,捕获后如果需要Quartz标记任务执行失败,可以重新抛出JobExecutionException,也可自定义配置是否重新执行
  • 参考代码实现:
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    Long batchId = System.currentTimeMillis();
    JobKey jobKey = context.getJobDetail().getKey();
    try {
        // 你的业务逻辑
        // 记录批次执行成功状态
    } catch (Exception e) {
        // 记录失败信息:落库/上报/告警
        System.out.printf("任务[%s]批次[%d]执行失败:%s%n", jobKey, batchId, e.getMessage());
        // 可选配置:设置失败后是否立即重试
        JobExecutionException je = new JobExecutionException(e);
        je.setRefireImmediately(false);
        throw je;
    }
}

方案3:持久化Job运行历史(适合需要长期追溯的场景)

  • 开启Quartz的JDBC持久化配置,所有任务的触发记录、执行状态会自动存入Quartz内置的库表
  • 直接查询QRTZ_FIRED_TRIGGERS表可查看当前正在执行的任务,查询QRTZ_JOB_DETAILS可拿到任务基础信息,配合业务侧存储的批次执行日志,可完整追溯每个任务的每一次运行情况
  • 如果需要更结构化的运行历史,可以在上述两种方案的基础上,把每次执行的批次号、任务标识、执行状态、耗时、失败原因都存入自定义的业务监控表,后续可直接对接可视化面板、配置失败统计规则、告警阈值等。

内容的提问来源于stack exchange,提问作者kushagra deep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:15:02