介绍
我在ASP.Net框架4、webforms 网站上使用Quartz.Net 。基本上,用户应该能够手动触发一个批处理脚本,该脚本异步处理存储在数据库中的数千条记录。用户可以随时停止或暂停,调整一些变量,并在需要时继续处理(剩余记录)。
代码已完成并在本地工作(开发者机器、win7、vs2010、sql server express 2008 R2)。
它还在本地服务器上进行了测试(win server 2008 R2,sql server express 2008 R2)。它在两种环境下都可以正常工作,并使用所有预编译的代码进行了测试。问题是,一旦部署在远程服务器上
(win server 2008 R2),它实际上应该在其中运行(托管环境,不共享,不集群),它不能完全工作(详见下文)。调度程序被创建,但触发器,因此工作,不会触发。
(注意:我知道你们中的一些人会建议使用 Quartz 作为 Windows 服务,但尽管这样做有好处,但我真的很想知道为什么它不能作为嵌入式解决方案工作,因为它应该工作得很好喜欢在当地做)
细节
Quartz 2.1.2
Common.Logging 2.1.2
Common.Logging.NLog 2.0.0
NLog 2.0.1.2
全球.asax
public static ISchedulerFactory SchedulerFactory;
public static IScheduler Scheduler;
void Application_Start(object sender, EventArgs e)
{
SchedulerFactory = new StdSchedulerFactory();
Scheduler = SchedulerFactory.GetScheduler();
// Define a durable job instance (durable jobs can exist without triggers)
IJobDetail job = JobBuilder.Create<MyJobClass>()
.WithIdentity("MyJob", "MyGroup")
.StoreDurably()
.Build();
Scheduler.AddJob(job, false);
Scheduler.Start();
}
void Application_End(object sender, EventArgs e)
{
Scheduler.Shutdown(true);
}
process.aspx.cs(点击开始按钮)
// get records from DB, iterate, process, etc
...
IJobDetail job = ASP.global_asax.Scheduler.GetJobDetail(new JobKey("MyJob", "MyGroup"));
job.JobDataMap.Put("something1", 1);
job.JobDataMap.Put("something2", somevar);
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("MyTrigger", "MyGroup")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever())
.Build();
var triggersSet = new Quartz.Collection.HashSet<ITrigger> { trigger };
ASP.global_asax.Scheduler.ScheduleJob(job, triggersSet, true);
日志输出
本地日志
Default Quartz.NET properties loaded from embedded resource file
Using default implementation for object serializer
Using default implementation for ThreadExecutor
Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
Quartz Scheduler v.2.1.2.400 created.
RAMJobStore initialized.
Scheduler meta-data: Quartz Scheduler (v2.1.2.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads. Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.
Quartz scheduler 'DefaultQuartzScheduler' initialized
Quartz scheduler version: 2.1.2.400
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
Batch acquisition of 0 triggers
Batch acquisition of 0 triggers
它继续记录0 触发器的批量获取,直到发生按钮单击:
Default Quartz.NET properties loaded from embedded resource file
Batch acquisition of 1 triggers
Producing instance of Job 'MyGroup.MyJob', class=MyJobClass
Batch acquisition of 0 triggers
Calling Execute on job MyGroup.MyJob
Trigger instruction : NoInstruction
Batch acquisition of 1 triggers
Producing instance of Job 'MyGroup.MyJob', class=MyJobClass
Batch acquisition of 0 triggers
Calling Execute on job MyGroup.MyJob
Trigger instruction : NoInstruction
Batch acquisition of 1 triggers
部署日志
Default Quartz.NET properties loaded from embedded resource file
Using default implementation for object serializer
Using default implementation for ThreadExecutor
Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
Quartz Scheduler v.2.1.2.400 created.
RAMJobStore initialized.
Scheduler meta-data: Quartz Scheduler (v2.1.2.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads. Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.
Quartz scheduler 'DefaultQuartzScheduler' initialized
Quartz scheduler version: 2.1.2.400
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
这里保持这样。如您所见,与其他日志相比,它并没有尝试获取触发器(0触发器的行批量获取根本没有出现)。如果您仍然单击进程按钮,则日志会添加一行:
Default Quartz.NET properties loaded from embedded resource file
但没有其他事情发生。记录未处理(我知道,因为每次处理记录时,都会在数据库中标记)。不会发生错误,但不会触发触发器,也不会执行作业。此外,单击按钮时 CPU 使用率高达 50% 或更多,并且不会下降,除非您转到 IIS,停止并重新启动应用程序池。这种 CPU 消耗不会在本地发生。
更新 1
正如 LeftyX 所建议的那样,更改了单例调度程序的使用,但在远程服务器上仍然得到相同的行为。
更新 2
我还尝试使用ADOJobStore(而不是我使用的RAMJobStore)。现在它仍然可以在本地完美运行;但仍然不在线执行触发器(因此工作)。唯一的区别是在线 CPU 使用率不会达到 50%。现在我可以看到作业和触发器已创建(我查询表并查看这些记录是否存在),但从未被执行。