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
相关产品推荐
相关产品推荐

