13

前書き

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% に達しないことです。そして今、ジョブとトリガーが作成されていることを確認できます (テーブルにクエリを実行し、それらのレコードが存在することを確認します)が、決して実行されません

4

4 に答える 4

4

この問題は、スケジューラー、などIISではなく、関連しています。一方、Web には多くの解決方法が投稿されていますが、それらの一部のみが機能しています。私の意見では、多くの構成設定を適用する必要はありません。アプリケーションを公開して楽しむサーバーにIIS 6.0/7.5 のキープ アライブ サービスをインストールするだけです。その後、公開されたアプリケーションは、アプリケーション プールのリサイクル、IIS/アプリケーションの再起動などの後に有効になります。これがお役に立てば幸いです...Quartz.NETHangfire

于 2015-11-12T13:07:38.967 に答える