Quartz scheduler 如何在Quartz.Net中处理作业恢复
我在使用.NET Core 2.2平台的应用程序中使用了Quartz 3.0.7。 我使用ms sql server进行Quartz操作跟踪。Quartz跟踪并将其动作存储在数据库中,一切正常。 我的StdSchedulerFactory的配置:Quartz scheduler 如何在Quartz.Net中处理作业恢复,quartz-scheduler,scheduling,quartz.net,job-scheduling,quartz,Quartz Scheduler,Scheduling,Quartz.net,Job Scheduling,Quartz,我在使用.NET Core 2.2平台的应用程序中使用了Quartz 3.0.7。 我使用ms sql server进行Quartz操作跟踪。Quartz跟踪并将其动作存储在数据库中,一切正常。 我的StdSchedulerFactory的配置: ["quartz.scheduler.instanceName"] = "StdScheduler", ["quartz.scheduler.instanceId"] = $"{Environment.M
["quartz.scheduler.instanceName"] = "StdScheduler",
["quartz.scheduler.instanceId"] = $"{Environment.MachineName}-{Guid.NewGuid()}",
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
["quartz.jobStore.useProperties"] = "true",
["quartz.jobStore.dataSource"] = "default",
["quartz.jobStore.tablePrefix"] = "QRTZ_",
// if running MS SQL Server we need this
["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz",
["quartz.dataSource.default.connectionString"] = @"Server=DESKTOP-D64SJFJ\MSSQLSERVER14;Database=quartz;Trusted_Connection=True;",
["quartz.dataSource.default.provider"] = "SqlServer",
[$"{StdSchedulerFactory.PropertyObjectSerializer}.type"] = "json",
[StdSchedulerFactory.PropertySchedulerInterruptJobsOnShutdownWithWait] = "true",
我想恢复每个被中断的作业。我应该如何组织我的IHostedService逻辑以支持工作恢复?
当我在作业运行期间关闭应用程序时,当我再次启动应用程序时,中断的作业不会运行。
我的IHostedService代码:
public class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<JobSchedule> _jobSchedules;
public QuartzHostedService(
ISchedulerFactory schedulerFactory,
IJobFactory jobFactory,
IEnumerable<JobSchedule> jobSchedules)
{
_schedulerFactory = schedulerFactory;
_jobSchedules = jobSchedules;
_jobFactory = jobFactory;
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;
await Scheduler.Start(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);
if (!await Scheduler.CheckExists(job.Key, cancellationToken))
{
// if the job doesn't already exist, we can create it, along with its trigger. this prevents us
// from creating multiple instances of the same job when running in a clustered environment
await Scheduler.ScheduleJob(job, trigger);
}
else
{
// if the job has exactly one trigger, we can just reschedule it, which allows us to update the schedule for
// that trigger.
var triggers = await Scheduler.GetTriggersOfJob(job.Key);
if (triggers.Count == 1)
{
await Scheduler.RescheduleJob(triggers.First().Key, trigger);
}
else
{
// if for some reason the job has multiple triggers, it's easiest to just delete and re-create the job,
// since we want to enforce a one-to-one relationship between jobs and triggers
await Scheduler.DeleteJob(job.Key);
await Scheduler.ScheduleJob(job, trigger);
}
}
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}
private static IJobDetail CreateJob(JobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName)
.WithDescription(jobType.Name)
.RequestRecovery(true)
.StoreDurably()
.Build();
}
private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
公共类QuartzHostedService:IHostedService
{
私有只读isSchedulerFactory\u schedulerFactory;
私有只读IJobFactory\u jobFactory;
私有只读IEnumerable\u作业计划;
公共托管服务(
IsSchedulerFactory schedulerFactory,
IJobFactory jobFactory,
i可数作业计划表)
{
_schedulerFactory=schedulerFactory;
_作业计划=作业计划;
_jobFactory=jobFactory;
}
公共ISScheduler调度程序{get;set;}
公共异步任务StartAsync(CancellationToken CancellationToken)
{
Scheduler=wait_schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory=\u JobFactory;
等待调度程序启动(cancellationToken);
foreach(var作业计划在_作业计划中)
{
var job=CreateJob(作业计划);
var trigger=CreateTrigger(作业计划);
如果(!wait Scheduler.check存在(job.Key,cancellationToken))
{
//如果作业不存在,我们可以创建它以及它的触发器。这会阻止我们
//在群集环境中运行时创建同一作业的多个实例
wait Scheduler.ScheduleJob(作业,触发器);
}
其他的
{
//如果作业只有一个触发器,我们可以重新安排它,这样我们就可以更新作业的计划
//那个扳机。
var triggers=wait Scheduler.GetTriggersOfJob(job.Key);
if(triggers.Count==1)
{
wait Scheduler.RescheduleJob(triggers.First().Key,trigger);
}
其他的
{
//如果由于某种原因,作业有多个触发器,则最简单的方法是删除并重新创建作业,
//因为我们想要在作业和触发器之间实现一对一的关系
wait Scheduler.DeleteJob(job.Key);
wait Scheduler.ScheduleJob(作业,触发器);
}
}
}
}
公共异步任务StopAsync(CancellationToken CancellationToken)
{
等待调度程序?关机(取消令牌);
}
专用静态IJobDetail CreateJob(作业时间表)
{
var jobType=schedule.jobType;
返回工
.Create(作业类型)
.WithIdentity(作业类型.全名)
.WithDescription(作业类型.名称)
.RequestRecovery(真)
.可储存的()
.Build();
}
专用静态ITrigger CreateTrigger(作业计划)
{
返回触发器生成器
.Create()
.WithIdentity($“{schedule.JobType.FullName}.trigger”)
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
My startup.cs:
private void ConfigureQuartz(IServiceCollection services)
{
services.AddHostedService<QuartzHostedService>();
services.AddSingleton<IJobFactory, SingletonJobFactory>();
services.AddSingleton<ISchedulerFactory>(new StdSchedulerFactory(StdSchedulerFactoryConfiguration()));
services.AddSingleton<AuthKeyExpiresJob>();
//services.AddSingleton<AuthKeyWillExpireJob>();
services.AddSingleton(new JobSchedule(
typeof(AuthKeyExpiresJob),
"0 14 11 ? * *"));
}
private void ConfigureQuartz(IServiceCollection服务)
{
services.AddHostedService();
services.AddSingleton();
AddSingleton(新的StdSchedulerFactory(StdSchedulerFactoryConfiguration());
services.AddSingleton();
//services.AddSingleton();
服务。添加Singleton(新作业计划(
类型(AuthKeyExpiresJob),
"0 14 11 ? * *"));
}