通过NuGet安装核心依赖:
Install-Package Quartz.Extensions.Hosting
Install-Package Quartz.Serialization.Json
# (可选)监控集成
Install-Package OpenTelemetry.Instrumentation.Quartz
在Program.cs
中配置Quartz服务和OpenTelemetry追踪:
var builder = WebApplication.CreateBuilder(args);
// 添加Quartz核心服务
builder.Services.AddQuartz();
// 将Quartz作为托管服务运行
builder.Services.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true; // 确保任务执行完成
});
// 集成OpenTelemetry实现分布式追踪
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation()
.AddQuartzInstrumentation(); // 关键:启用Quartz追踪
})
.UseOtlpExporter(); // 导出指标到OpenTelemetry后端
所有Quartz作业必须实现IJob
接口,支持依赖注入和作用域服务:
public classEmailReminderJob : IJob
{
publicconststring Name = "EmailReminderJob";
privatereadonly ILogger<EmailReminderJob> _logger;
privatereadonly IEmailService _emailService;
public EmailReminderJob(ILogger<EmailReminderJob> logger, IEmailService emailService)
{
_logger = logger;
_emailService = emailService;
}
public async Task Execute(IJobExecutionContext context)
{
// 推荐使用合并后的JobDataMap获取参数
var data = context.MergedJobDataMap;
string? userId = data.GetString("userId");
string? message = data.GetString("message");
try
{
await _emailService.SendReminderAsync(userId, message);
_logger.LogInformation("已向用户{UserId}发送提醒:{Message}", userId, message);
}
catch (Exception ex)
{
_logger.LogError(ex, "发送提醒失败(用户:{UserId})", userId);
throw; // 触发Quartz重试机制
}
}
}
通过API端点创建定时任务:
[HttpPost("api/reminders/schedule")]
public async Task<IActionResult> ScheduleReminder([FromBody] ScheduleReminderRequest request)
{
var scheduler = await _schedulerFactory.GetScheduler();
var jobData = new JobDataMap
{
{ "userId", request.UserId },
{ "message", request.Message }
};
var job = JobBuilder.Create<EmailReminderJob>()
.WithIdentity($"reminder-{Guid.NewGuid()}", "email-reminders") // 唯一标识符
.SetJobData(jobData)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity($"trigger-{Guid.NewGuid()}", "email-reminders")
.StartAt(request.ScheduleTime)
.Build();
await scheduler.ScheduleJob(job, trigger);
return Ok(new { scheduled = true, scheduledTime = request.ScheduleTime });
}
请求示例:
POST /api/reminders/schedule
{
"userId": "user123",
"message": "重要会议提醒!",
"scheduleTime": "2024-12-17T15:00:00"
}
通过CRON表达式实现复杂调度策略:
[HttpPost("api/reminders/schedule/recurring")]
public async Task<IActionResult> ScheduleRecurringReminder([FromBody] RecurringReminderRequest request)
{
var scheduler = await _schedulerFactory.GetScheduler();
var jobData = new JobDataMap
{
{ "userId", request.UserId },
{ "message", request.Message }
};
var job = JobBuilder.Create<EmailReminderJob>()
.WithIdentity($"recurring-{Guid.NewGuid()}", "recurring-reminders")
.SetJobData(jobData)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity($"recurring-trigger-{Guid.NewGuid()}", "recurring-reminders")
.WithCronSchedule(request.CronExpression) // 支持秒/分/时/日/月/年
.Build();
await scheduler.ScheduleJob(job, trigger);
return Ok(new { scheduled = true, cronExpression = request.CronExpression });
}
请求示例:
POST /api/reminders/schedule/recurring
{
"userId": "user123",
"message": "每日站会提醒",
"cronExpression": "0 0 10 ? * MON-FRI" // 每周一至周五上午10点执行
}
配置PostgreSQL存储并创建专用schema:
builder.Services.AddQuartz(options =>
{
options.AddJob<EmailReminderJob>(c => c
.StoreDurably() // 标记为持久化作业
.WithIdentity(EmailReminderJob.Name));
options.UsePersistentStore(persistenceOptions =>
{
persistenceOptions.UsePostgres(cfg =>
{
cfg.ConnectionString = _configuration["ConnectionStrings:Postgres"];
cfg.TablePrefix = "scheduler.qrtz_"; // 数据表前缀隔离
},
dataSourceName: "reminders"); // 数据库名称
persistenceOptions.UseNewtonsoftJsonSerializer(); // 使用JSON序列化
persistenceOptions.UseProperties = true; // 启用JobDataMap存储
});
});
通过唯一标识符引用预定义作业:
public async Task ScheduleReminder(string userId, string message, DateTime scheduledTime)
{
var scheduler = await _schedulerFactory.GetScheduler();
var jobKey = new JobKey(EmailReminderJob.Name);
var trigger = TriggerBuilder.Create()
.ForJob(jobKey)
.WithIdentity($"trigger-{Guid.NewGuid()}")
.UsingJobData("userId", userId)
.UsingJobData("message", message)
.StartAt(scheduledTime)
.Build();
await scheduler.ScheduleJob(trigger); // 仅传递Trigger对象
}
通过以下配置实现全链路追踪:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation()
.AddQuartzInstrumentation(); // 关键:捕获Quartz调度事件
})
.UseOtlpExporter();
在作业执行中捕获异常并触发重试:
try
{
await _emailService.SendReminderAsync(userId, message);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "邮件发送失败,已触发重试机制");
throw; // Quartz自动处理重试逻辑
}
本文完整覆盖了Quartz.NET在ASP.NET Core中的核心应用场景: ✅ 基础架构搭建:服务注册、追踪集成 ✅ 作业生命周期管理:定义、调度、持久化 ✅ 高级调度策略:CRON表达式、循环任务 ✅ 生产级保障:数据库存储、错误重试、监控 ✅ 最佳实践:JobDataMap安全使用、作业标识符管理
通过合理运用这些技术,您可以构建出高可靠、易维护的异步任务处理系统。后续可扩展实现: • 分布式任务队列:结合RabbitMQ实现最终一致性 • 任务状态查询API:暴露作业执行状态接口 • 自动重试策略配置:自定义重试次数和间隔
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有