Quartz 后台工作者管理

Quartz是一个高级的后台工作者管理. 你可以用ABP框架集成Quartz代替默认后台工作者管理. ABP简单的集成了Quartz.

安装

建议使用ABP CLI安装包.

使用ABP CLI

在项目的文件夹(.csproj文件)中打开命令行窗口输入以下命令:

  1. abp add-package Volo.Abp.BackgroundWorkers.Quartz

手动安装

如果你想手动安装;

  1. 添加 Volo.Abp.BackgroundWorkers.Quartz NuGet包添加到你的项目:

    1. Install-Package Volo.Abp.BackgroundWorkers.Quartz
  2. 添加 AbpBackgroundWorkersQuartzModule 到你的模块的依赖列表:

  1. [DependsOn(
  2. //...other dependencies
  3. typeof(AbpBackgroundWorkersQuartzModule) //Add the new module dependency
  4. )]
  5. public class YourModule : AbpModule
  6. {
  7. }

Quartz后台工作者集成提供了 QuartzPeriodicBackgroundWorkerAdapter 来适配 PeriodicBackgroundWorkerBaseAsyncPeriodicBackgroundWorkerBase 派生类. 所以你依然可以按照后台工作者文档来定义后台作业. BackgroundJobWorker 每5秒检查待执行作业,但是长时间的作业不会阻塞quartz. 所以安装Quartz后台工作者集成后,你同时需要安装Quartz后台作业Hangfire后台作业以避免重复执行作业.

配置

参阅配置.

创建后台工作者

后台工作者是一个继承自 QuartzBackgroundWorkerBase 基类的类. 一个简单的工作者如下所示:

  1. public class MyLogWorker : QuartzBackgroundWorkerBase
  2. {
  3. public MyLogWorker()
  4. {
  5. JobDetail = JobBuilder.Create<MyLogWorker>().WithIdentity(nameof(MyLogWorker)).Build();
  6. Trigger = TriggerBuilder.Create().WithIdentity(nameof(MyLogWorker)).StartNow().Build();
  7. }
  8. public override Task Execute(IJobExecutionContext context)
  9. {
  10. Logger.LogInformation("Executed MyLogWorker..!");
  11. return Task.CompletedTask;
  12. }
  13. }

示例中我们重写了 Execute 方法写入日志. 后台工作者默认是单例. 如果你需要,也可以实现依赖接口将其注册为其他的生命周期.

提示: 为后台工作者添加标识是最佳实践,Quartz根据标识区分作业. 如果未指定标识会重复添加工作者到Quartz.

添加到BackgroundWorkerManager

默认后台工作者会在应用程序启动时自动添加到 BackgroundWorkerManager,如果你想要手动添加,可以将 AutoRegister 属性值设置为 false:

  1. public class MyLogWorker : QuartzBackgroundWorkerBase
  2. {
  3. public MyLogWorker()
  4. {
  5. AutoRegister = false;
  6. JobDetail = JobBuilder.Create<MyLogWorker>().WithIdentity(nameof(MyLogWorker)).Build();
  7. Trigger = TriggerBuilder.Create().WithIdentity(nameof(MyLogWorker)).StartNow().Build();
  8. }
  9. public override Task Execute(IJobExecutionContext context)
  10. {
  11. Logger.LogInformation("Executed MyLogWorker..!");
  12. return Task.CompletedTask;
  13. }
  14. }

尽管你可以使用 AutoRegister 跳过自动添加,但如果你想要全局禁用这样会比较繁琐. 你可以通过 AbpBackgroundWorkerQuartzOptions 选项全局禁用:

  1. [DependsOn(
  2. //...other dependencies
  3. typeof(AbpBackgroundWorkersQuartzModule) //Add the new module dependency
  4. )]
  5. public class YourModule : AbpModule
  6. {
  7. public override void ConfigureServices(ServiceConfigurationContext context)
  8. {
  9. Configure<AbpBackgroundWorkerQuartzOptions>(options =>
  10. {
  11. options.IsAutoRegisterEnabled = false;
  12. });
  13. }
  14. }

高级主题

自定义ScheduleJob

例如你有一个每10分钟执行一次的工作者,但由于服务器不可用30分钟导致工作者错过了3次执行,你想要在服务器恢复正常后执行所有错过的执行. 你应该这样定义你的工作者:

  1. public class MyLogWorker : QuartzBackgroundWorkerBase
  2. {
  3. public MyLogWorker()
  4. {
  5. JobDetail = JobBuilder.Create<MyLogWorker>().WithIdentity(nameof(MyLogWorker)).Build();
  6. Trigger = TriggerBuilder.Create().WithIdentity(nameof(MyLogWorker)).WithSimpleSchedule(s=>s.WithIntervalInMinutes(1).RepeatForever().WithMisfireHandlingInstructionIgnoreMisfires()).Build();
  7. ScheduleJob = async scheduler =>
  8. {
  9. if (!await scheduler.CheckExists(JobDetail.Key))
  10. {
  11. await scheduler.ScheduleJob(JobDetail, Trigger);
  12. }
  13. };
  14. }
  15. public override Task Execute(IJobExecutionContext context)
  16. {
  17. Logger.LogInformation("Executed MyLogWorker..!");
  18. return Task.CompletedTask;
  19. }
  20. }

在示例中我们定义了工作者执行间隔为10分钟,并且设置 WithMisfireHandlingInstructionIgnoreMisfires ,另外自定义 ScheduleJob 仅当工作者不存在时向quartz添加调度作业.

更多

参阅Quartz文档了解更多信息.