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

Quartz.NET调度器在Azure环境无法运行的问题排查与解决

解决Azure上Quartz.NET调度器不工作的方案

首先贴出你使用的调度器代码:

IJobDetail testjob = JobBuilder.Create<TestJob>()
                    .WithIdentity("rrtestjob", "rrtestgroup1")
                    .Build();
ITrigger testtrigger = TriggerBuilder.Create()
                   .WithIdentity("rrtesttrigger1", "rrtestgroup1")
                     .StartNow()
                    .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(29))
                    .Build();
await _quartzScheduler.ScheduleJob(testjob, testtrigger);
if (!_quartzScheduler.IsStarted)
  await _quartzScheduler.Start();

针对Azure环境下的问题,可按以下步骤排查解决:

1. 替换内存存储为持久化存储

Azure App Service是无状态环境,内存存储的Quartz调度信息会在应用重启(部署、缩放、应用池回收)时丢失,必须配置持久化存储:

  • Azure SQL Database:配置Quartz使用ADO.NET JobStore,示例appsettings.json配置:
"Quartz": {
  "Scheduler": {
    "InstanceId": "AUTO",
    "InstanceName": "QuartzScheduler"
  },
  "JobStore": {
    "Type": "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
    "DriverDelegateType": "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",
    "TablePrefix": "QRTZ_",
    "DataSource": "Default",
    "UseProperties": "true"
  },
  "DataSources": {
    "Default": {
      "ConnectionString": "你的Azure SQL连接字符串",
      "Provider": "SqlServer"
    }
  }
}
  • Azure Redis:安装Quartz.Extensions.Redis包,配置Redis连接信息实现分布式存储。

2. 用Hosted Service托管Scheduler

在ASP.NET Core中,必须将Quartz Scheduler作为后台服务托管,避免请求结束后Scheduler被回收。示例代码:

public class QuartzHostedService : IHostedService
{
    private readonly ISchedulerFactory _schedulerFactory;
    private IScheduler _scheduler;

    public QuartzHostedService(ISchedulerFactory schedulerFactory)
    {
        _schedulerFactory = schedulerFactory;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
        
        // 注册Job和Trigger
        IJobDetail testjob = JobBuilder.Create<TestJob>()
            .WithIdentity("rrtestjob", "rrtestgroup1")
            .Build();
        ITrigger testtrigger = TriggerBuilder.Create()
            .WithIdentity("rrtesttrigger1", "rrtestgroup1")
            .StartAt(DateTimeOffset.UtcNow.AddSeconds(5)) // 延迟启动,避免应用初始化未完成
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(29))
            .Build();
        await _scheduler.ScheduleJob(testjob, testtrigger, cancellationToken);
        
        await _scheduler.Start(cancellationToken);
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        await _scheduler?.Shutdown(cancellationToken);
    }
}

在Program.cs中注册服务:

builder.Services.AddQuartz();
builder.Services.AddQuartzHostedService(options =>
{
    options.WaitForJobsToComplete = true;
});
builder.Services.AddHostedService<QuartzHostedService>();

3. 排查Azure环境日志

开启Azure App Service日志功能定位具体错误:

  • 进入Azure门户的App Service,点击「监控」->「日志流」,实时查看应用运行日志。
  • 开启「诊断设置」,将日志发送到Log Analytics,搜索Quartz相关关键词,排查数据库连接失败、权限不足等问题。

4. 调整触发器与应用池配置

  • 把StartNow()替换为StartAt(DateTimeOffset.UtcNow.AddSeconds(5)),给应用初始化留足时间,避免触发器在应用未就绪时启动。
  • 检查应用池回收规则:进入「配置」->「常规设置」,调大「回收时间间隔」(建议24小时以上),禁用不必要的「基于内存的回收」规则。

5. 验证版本兼容性

确保Quartz.NET版本与Azure App Service的.NET运行时兼容:

  • 若使用.NET 6/7/8,建议使用Quartz.NET 3.3.x及以上稳定版本。
  • 清理NuGet缓存,重新部署应用,避免依赖冲突。

内容的提问来源于stack exchange,提问作者Hunzla Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:47:40