Quartz 重新安排作业
针对需要重新安排作业的需求,有几种处理方法。
手动重试
当 Quartz 作业正在运行时,若未处理的异常逃离了 IJob
方法,Quartz 系统会将作业标记为错误状态。随后,你可以使用适合你系统中的任意方法重新安排该作业。
使用 JobExecutionException
一个简单的方法是利用 JobExecutionException
控制作业是否应立即重新触发。
public async Task Execute(IJobExecutionContext context)
{
try
{
// 执行作业逻辑
}
catch (Exception ex)
{
throw new JobExecutionException(ex, refireImmediately: true)
{
UnscheduleFiringTrigger = true,
UnscheduleAllTriggers = true
};
}
}
Polly 重试
如果作业仅仅需要重试其工作,你可以使用 Polly 策略将作业包裹起来,并利用策略定义来实现重试。请注意,使用 Polly 实现长时间重试会保持一个作业槽位,从而阻止作业引擎执行更多工作。
自我重新安排
如果你的作业需要更多时间,比如需要等待 5 分钟,IJobExecutionContext
可以访问调度器。你可以利用它来重新安排作业,并使其正常退出。
public async Task Execute(IJobExecutionContext context)
{
// 某些情况发生,指示你需要延迟处理
// 例如收到HTTP 429 - 请求过多的状态码
var oldTrigger = context.Trigger;
var newTrigger = TriggerBuilder.Create()
.WithIdentity($"{oldTrigger.Key.Name}-retry", oldTrigger.Key.Group)
.StartAt(DateTimeOffset.UtcNow.AddMinutes(5))
.Build();
await context.Scheduler.ScheduleJob(newTrigger);
}
自我取消安排
另一种方法是让作业每 5 分钟(或其他合适的时间间隔)运行一次,成功后自行取消。这种方法的优点是逻辑上更容易理解,但仍可能持续对下游服务进行调用。
public async Task Execute(IJobExecutionContext context)
{
// 工作成功
if(success)
{
await context.Scheduler.UnscheduleJob(context.Trigger.Key);
}
}