Quartz.NET无法加载SQL Server数据库中定义的作业与触发器求助
Quartz.NET无法加载数据库中定义的作业和触发器问题
我已在SQL Server数据库中定义了作业和触发器,但Quartz.NET无法加载作业也无法触发触发器。确认存在操作失误但无法定位,查阅官方文档仍未解决,寻求帮助。
启动日志
Using job store 'Quartz.Impl.AdoJobStore.JobStoreTX', supports persistence: True, clustered: True {"@t":"2024-07-08T14:10:24.3246282Z","@mt":"Using job store 'Quartz.Impl.AdoJobStore.JobStoreTX', supports persistence: True, clustered: True","SourceContext":"Quartz.Impl.StdSchedulerFactory","SFTPService":"SFTPService"} {"@t":"2024-07-08T14:10:24.3328792Z","@mt":"Adding 0 jobs, 0 triggers.","SourceContext":"Quartz.ContainerConfigurationProcessor","SFTPService":"SFTPService"}
C#控制台应用Quartz初始化代码
//------------------------------------------------------------------------- // Setup Quartz the timer scheduling library //------------------------------------------------------------------------- services.AddQuartzHostedService(opt => { opt.WaitForJobsToComplete = true; }); services.AddQuartz(q=> { q.UsePersistentStore(s => { s.UseProperties = true; s.UseNewtonsoftJsonSerializer(); s.UseSqlServer(sqlServer => { sqlServer.ConnectionString = configuration.GetConnectionString("Quartz") ?? throw new ArgumentNullException("Quartz connection string"); sqlServer.TablePrefix = "QRTZ_"; }); s.UseClustering(c => { c.CheckinInterval = TimeSpan.FromSeconds(10); c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); }); }); });
数据库作业创建脚本
INSERT INTO QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP, JOB_CLASS_NAME, IS_DURABLE, IS_NONCONCURRENT, IS_UPDATE_DATA, REQUESTS_RECOVERY, JOB_DATA) VALUES ('SFTPService', 'SFTPDownloadJobName', 'SFTPJobGroup', 'MyCompany.SFTP.WorkerLibrary.SFTPDownloadJob, MyCompany.SFTP.WorkerLibrary', 1, 0, 0, 0, NULL); INSERT INTO QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, JOB_NAME, JOB_GROUP, DESCRIPTION, NEXT_FIRE_TIME, PREV_FIRE_TIME, PRIORITY, TRIGGER_STATE, TRIGGER_TYPE, START_TIME, END_TIME, CALENDAR_NAME, MISFIRE_INSTR, JOB_DATA) VALUES ('SFTPService', 'FrequentTriggerName', 'FrequentTriggerGroup', 'SFTPDownloadJobName', 'SFTPJobGroup', 'Fires every 20 seconds', NULL, NULL, 5, 'WAITING', 'CRON', DATEDIFF(SECOND, '1970-01-01', GETDATE()), NULL, NULL, 0, NULL); INSERT INTO QRTZ_CRON_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, CRON_EXPRESSION, TIME_ZONE_ID) VALUES ('SFTPService', 'FrequentTriggerName', 'FrequentTriggerGroup', '0/20 * * * * ?', NULL); DECLARE @jsonData NVARCHAR(MAX) = '{ "SftpHostName": "eu-central-1.sftpcloud.io", "SftpPortNumber": "22", "SftpUserName": "*********************", "SftpPassword": "***********************", "SftpRemoteDirectory": "/", "SftpLocalDirectory": "", "SftpFileNameOrPattern": "test.txt" }'; DECLARE @jobData VARBINARY(MAX) = CONVERT(VARBINARY(MAX), @jsonData); UPDATE QRTZ_TRIGGERS SET JOB_DATA = @jobData WHERE SCHED_NAME = 'SFTPService' AND TRIGGER_NAME = 'FrequentTriggerName' AND TRIGGER_GROUP = 'FrequentTriggerGroup';
问题排查与解决方案
1. 调度器名称不匹配(核心问题)
Quartz默认调度器名称为QuartzScheduler,但数据库中所有作业/触发器的SCHED_NAME是SFTPService,两者不匹配导致Quartz无法识别数据库中的记录。
修复方法:在Quartz初始化时显式指定调度器名称:
services.AddQuartz(q=> { // 添加以下两行 q.SchedulerName = "SFTPService"; q.SchedulerId = "SFTPService-Node1"; // 集群模式下每个节点ID需唯一 q.UsePersistentStore(s => { // 原有配置... }); });
2. JobData序列化格式不兼容
手动将JSON转成VARBINARY存储到JOB_DATA字段,但Quartz使用Newtonsoft.Json序列化时会包含特定类型信息,直接转换的JSON无法被正确解析。
修复方法:
- 避免手动修改
JOB_DATA,改用Quartz API添加作业时传入JobDataMap,让框架自动处理序列化。 - 若必须手动插入,需确保序列化格式与Quartz一致,可通过以下代码生成正确的JOB_DATA:
var jobDataMap = new JobDataMap { ["SftpHostName"] = "eu-central-1.sftpcloud.io", ["SftpPortNumber"] = "22", // 其他参数... }; var serializer = new NewtonsoftJsonObjectSerializer(); byte[] serializedData = serializer.Serialize(jobDataMap); // 将serializedData存入数据库JOB_DATA字段
3. 触发器启动时间与状态验证
- 检查
START_TIME是否为UTC时间戳:Quartz内部使用UTC时间,需将DATEDIFF(SECOND, '1970-01-01', GETDATE())改为DATEDIFF(SECOND, '1970-01-01', GETUTCDATE())。 - 集群模式下,触发器状态
WAITING需要Quartz节点正常注册后才能激活,确保数据库连接正常,QRTZ_SCHEDULER_STATE表中有当前节点的记录。
4. 作业类程序集名称验证
确认JOB_CLASS_NAME中的程序集名称完全匹配,包括版本、文化和公钥标记(如果程序集是强签名的)。可通过以下代码获取正确的程序集限定名:
typeof(SFTPDownloadJob).AssemblyQualifiedName
内容的提问来源于stack exchange,提问作者Bigtoe
相关产品推荐
相关产品推荐

