是否可以添加带有触发器的作业来运行Quartz.NET调度程序实例而无需重新启动服务器?
答案 0 :(得分:7)
ADOJobStore的一个相当强大的实现是拥有一个自定义表来存储作业,并创建一个继承自ISchedulerPlugin和IJob的类,以自动为您的作业创建计划。
您的配置如下所示:
<add key="quartz.plugin.sqlquartzjobs.type" value="(JobSchedulerPlugin assembly path)" />
<add key="quartz.plugin.sqlquartzjobs.RescanCronExpression" value="0 0/5 * * * ?" /> //plugin should fire every five minutes
<add key="quartz.plugin.sqlquartzjobs.ConnectionString" value="(your connection string)" />
您的插件/工作类可能如下所示:
public class JobSchedulerPlugin : ISchedulerPlugin, IJob
{
//Entry point for plugin, quartz server runs when it starts
public void Initialize(string pluginName, IScheduler sched)
{
Name = pluginName;
Scheduler = sched;
}
//Runs after Initialize()
public void Start()
{
//schedule plugin as a job
JobDataMap jobData = new JobDataMap();
jobData["ConnectionString"] = ConnectionString;
IJobDetail job = JobBuilder.Create(this.GetType())
.WithDescription("Job to rescan jobs from SQL db")
.WithIdentity(new JobKey(JobInitializationPluginJobName, JobInitializationPluginGroup))
.UsingJobData(jobData)
.Build();
TriggerKey triggerKey = new TriggerKey(JobInitializationPluginJobTriggerName, JobInitializationPluginGroup);
ITrigger trigger = TriggerBuilder.Create()
.WithCronSchedule(ConfigFileCronExpression)
.StartNow()
.WithDescription("trigger for sql job loader")
.WithIdentity(triggerKey)
.WithPriority(1)
.Build();
Scheduler.ScheduleJob(job, trigger);
}
}
现在,JobSchedulerPlugin已经进入QRTZ_TRIGGERS的触发器,该触发器将以最高优先级每五分钟触发一次。您可以使用它从自定义表中加载作业(让我们称之为QUARTZJOBS)。 QUARTZJOBS可以包含诸如工作名,装配路径,日期,状态等信息,以及可用于帮助您有效创建触发器的任何信息。它还应该包含作业的cron表达式。这是触发器触发时可以执行的操作:
//Entry point of every job
public void Execute(IJobExecutionContext context)
{
Scheduler = context.Scheduler;
JobCollection jobs = LoadJobs(context.JobDetail.JobDataMap["ConnectionString"].ToString());
JobsWithTriggers jobTriggers = CreateTriggers(jobs);
SchedulerJob(jobTriggers);
}
//You can use ADO.NET or an ORM here to load job information from the the table
//and push it into a class.
protected JobCollection LoadJobs(string connectionString);
//In this class you can create JobDetails and ITriggers for each job
//and push them into a custom class
protected JobsWithTriggers CreateTriggers(jobs);
//Finally here you can schedule the jobs
protected void ScheduleJobs(jobstriggers)
在上面的每个类中,您可以添加自定义验证,以确保在状态或cron表达式发生更改时正确处理触发器。
使用此解决方案,永远不需要重新启动服务器。插件/作业类将扫描表并采取相应的行动。
答案 1 :(得分:0)
您的数据存储是什么?
这是一个场景......有点偏僻:
您可以编写一个小型控制台应用程序(或类似的),即“Job Populater”。
您可以将其连接到从xml文件中提取作业定义,然后将它们推送到ADO数据存储区(sql server)。
这是我的石英配置:
<quartz>
<!--
This configuration is a way to have jobs defined in xml, but will get them written to the database.
See https://stackoverflow.com/questions/21589964/ramjobstore-quartz-jobs-xml-to-adojobstore-data-move/
-->
<add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
<add key="quartz.plugin.xml.fileNames" value="~/Quartz_Jobs_001.xml" />
<!--
<add key="quartz.plugin.xml.ScanInterval" value="10" />
-->
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/>
<add key="quartz.jobStore.dataSource" value="default"/>
<add key="quartz.dataSource.default.connectionString" value="Server=MyServer\MyInstance;Database=QuartzDB;Trusted_Connection=True;Application Name='quartz_config';"/>
<add key="quartz.dataSource.default.provider" value="SqlServer-20"/>
</quartz>
哪个(正如你在xml的评论中看到的那样),我得到了帮助。
这是原作: RAMJobStore (quartz_jobs.xml) to AdoJobStore Data Move