如何捕获Quartz Scheduler因故障终止或崩溃的事件?
如何捕获Quartz Scheduler的终止或崩溃事件?
当然可以实现!Quartz提供了专门的机制来监听调度器的生命周期事件,包括崩溃、意外终止这类场景,下面我给你详细说说具体的实现方式:
方法一:使用SchedulerListener监听调度器核心事件
Quartz的SchedulerListener接口(或者更方便的抽象类SchedulerListenerSupport)可以监听调度器的错误、关闭、启动等关键事件,非常适合捕获你说的数据库连接中断导致的崩溃场景。
1. 自定义调度器监听器
先实现一个自定义的监听器,只需要重写你关心的事件方法:
public class CustomSchedulerListener : SchedulerListenerSupport { private readonly ILogger _logger; public CustomSchedulerListener(ILogger logger) { _logger = logger; } // 捕获调度器发生的错误(比如ADO Job Store数据库连接中断) public override Task SchedulerError(string msg, SchedulerException cause) { _logger.Fatal($"调度器触发错误: {msg}", cause); // 这里可以添加自定义告警逻辑,比如推送通知、记录到监控系统 QuartzScedulerMessage = $"调度器异常: {cause.Message}"; return base.SchedulerError(msg, cause); } // 监听调度器开始关闭的事件 public override Task SchedulerShuttingdown() { _logger.Info("调度器正在关闭"); QuartzScedulerMessage = "调度器正在关闭"; return base.SchedulerShuttingdown(); } // 监听调度器完成关闭的事件 public override Task SchedulerShutdown() { _logger.Info("调度器已关闭"); QuartzScedulerMessage = "调度器已关闭"; return base.SchedulerShutdown(); } }
2. 在调度器启动时注册监听器
修改你现有的启动代码,把自定义监听器注册到调度器中:
internal static IScheduler MyQuartzScheduler = null; private static async void StartProcessing() { try { Logger.Info("Starting Quartz"); StdSchedulerFactory factory = new StdSchedulerFactory(); MyQuartzScheduler = await factory.GetScheduler(); // 注册自定义调度器监听器 await MyQuartzScheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener(Logger)); await MyQuartzScheduler.Start(); QuartzScedulerMessage = string.Format("Quartz Scheduler Started on {0}", DateTime.Now); } catch (Exception ex) { QuartzScedulerMessage = ex.Message; Logger.Fatal(ex.Message, ex); } }
方法二:定期检查调度器状态(可选)
除了被动监听事件,你还可以主动定期检查调度器的运行状态,确保在某些极端场景下(比如监听器未捕获到的异常)也能发现问题:
private static async Task CheckSchedulerStatusPeriodically() { while (true) { await Task.Delay(TimeSpan.FromMinutes(5)); // 每5分钟检查一次 if (MyQuartzScheduler != null && MyQuartzScheduler.IsShutdown) { Logger.Fatal("调度器已意外关闭,尝试重启..."); // 这里可以加入重启逻辑,或者触发告警通知 await RestartScheduler(); } } } private static async Task RestartScheduler() { try { if (MyQuartzScheduler != null) { await MyQuartzScheduler.Shutdown(); } StdSchedulerFactory factory = new StdSchedulerFactory(); MyQuartzScheduler = await factory.GetScheduler(); await MyQuartzScheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener(Logger)); await MyQuartzScheduler.Start(); QuartzScedulerMessage = $"调度器已重启,时间: {DateTime.Now}"; Logger.Info("调度器重启成功"); } catch (Exception ex) { QuartzScedulerMessage = $"重启调度器失败: {ex.Message}"; Logger.Fatal("重启调度器失败", ex); } }
一些注意事项
- 确保你的日志框架(比如NLog、Serilog)配置正确,Quartz内部的日志能帮你快速定位问题根源。
- 针对ADO Job Store的数据库连接问题,大部分异常都会被
SchedulerError方法捕获,不过你也可以结合数据库连接池的监控来提前预警。 - 如果需要监听单个任务的执行异常,可以实现
IJobListener接口,做更细粒度的监控。
内容的提问来源于stack exchange,提问作者Kamran Shahid
相关产品推荐
相关产品推荐

