如何监控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
相关产品推荐
相关产品推荐

