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

如何捕获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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:05