前書き
ASP.Netフレームワーク 4、webforms Web サイトで Quartz.Netを使用しています。基本的に、ユーザーは、データベースに格納された数千のレコードを非同期的に処理するバッチ スクリプトを手動で起動できる必要があります。ユーザーはいつでも停止または一時停止し、いくつかの変数を調整し、必要に応じてプロセスを続行できます (残りのレコード)。
コードが完成し、ローカルで動作しています (開発者マシン、win7、vs2010、SQL Server Express 2008 R2)。
また、ローカル サーバー (win サーバー 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 トリガーのバッチ取得はまったく表示されません)。とにかく処理ボタンをクリックすると、ログに 1 行追加されます。
Default Quartz.NET properties loaded from embedded resource file
しかし、他に何も起こりません。レコードは処理されません (レコードが処理されるたびにデータベースでマークされるので、私は知っています)。エラーは発生しませんが、トリガーは起動されず、ジョブは実行されません。また、ボタンをクリックすると CPU 使用率が最大 50% 以上になり、IIS に移動してアプリケーション プールを停止して再起動しない限り、CPU 使用率は下がりません。この CPU 消費はローカルでは発生しません。
更新 1
LeftyX で提案されているように、 singletonのスケジューラの使用を変更しましたが、リモート サーバーでも同じ動作が得られます。
更新 2
また、(使用していたRAMJobStoreの代わりに) ADOJobStoreを使用しようとしました。今でもローカルで完全に動作します。ただし、まだトリガー(したがってジョブ)を online 実行しません。唯一の違いは、オンラインの CPU 使用率が 50% に達しないことです。そして今、ジョブとトリガーが作成されていることを確認できます (テーブルにクエリを実行し、それらのレコードが存在することを確認します)が、決して実行されません。