2011-01-28 8 views
1

Quartz Enterprise Job Scheduler(1.8.3)を使用しています。ジョブの構成はいくつかのXMLファイルから行われ、これらのXMLファイルの変更を検出してジョブを再スケジュールする特別なジョブがあります。これはうまく動作しますが、問題は自分自身を再スケジュールするためにこの "スケジューラジョブ"も必要であるということです。一度この仕事が自分自身を再スケジュールすると、何らかの理由で何度も実行されることがわかります。しかし、例外はありません。Quartz Enterprise Scheduler:自分自身をスケジューリングするジョブ

私は問題を複製して隔離しました。これは、エントリ・ポイントのようになります。

public class App { 
    public static void main(final String[] args) throws ParseException, SchedulerException { 
    // get the scheduler from the factory 
    final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 

    // start the scheduler 
    scheduler.start(); 

    // schedule the job to run every 20 seconds 
    final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class);   
    final Trigger trigger = new CronTrigger("triggername", "groupname", "*/20 * * * * ?"); 

    // set the scheduler in the job data map, so the job can re-configure itself 
    jobDetail.getJobDataMap().put("scheduler", scheduler); 

    // schedule job 
    scheduler.scheduleJob(jobDetail, trigger); 

    } 
} 

そして、これは、ジョブ・クラスのようになります。

public class TestJob implements Job { 

private final static Logger LOG = Logger.getLogger(TestJob.class); 
private final static AtomicInteger jobExecutionCount = new AtomicInteger(0); 

public void execute(final JobExecutionContext context) throws JobExecutionException { 
    // get the scheduler from the data map 
    final Scheduler scheduler = (Scheduler) context.getJobDetail().getJobDataMap().get("scheduler"); 
    LOG.info("running job! " + jobExecutionCount.incrementAndGet()); 

    // buid the job detail and trigger 
    final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class); 
    // this time, schedule it to run every 35 secs 
    final Trigger trigger; 
    try { 
     trigger = new CronTrigger("triggername", "groupname", "*/50 * * * * ?"); 
    } catch (final ParseException e) { 
     throw new JobExecutionException(e); 
    } 
    trigger.setJobName("jobname"); 
    trigger.setJobGroup("groupname"); 

    // set the scheduler in the job data map, so this job can re-configure itself 
    jobDetail.getJobDataMap().put("scheduler", scheduler); 

    try { 
     scheduler.rescheduleJob(trigger.getName(), jobDetail.getGroup(), trigger); 
    } catch (final SchedulerException e) { 
     throw new JobExecutionException(e); 
    } 
} 
} 

私はscheduler.rescheduleJobで、その後scheduler.deleteJobscheduler.scheduleJobと両方試してみました。 22:20018、ジョブは正常に動作23でどのように

23:22:15,874   INFO SchedulerSignalerImpl:60 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 
23:22:15,878   INFO QuartzScheduler:219 - Quartz Scheduler v.1.8.3 created. 
23:22:15,883   INFO RAMJobStore:139 - RAMJobStore initialized. 
23:22:15,885   INFO QuartzScheduler:241 - Scheduler meta-data: Quartz Scheduler (v1.8.3) 

'MyScheduler' with instanceId '1' 
    Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. 
    NOT STARTED. 
    Currently in standby mode. 
    Number of jobs executed: 0 
    Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads. 
    Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered. 

23:22:15,885   INFO StdSchedulerFactory:1275 - Quartz scheduler 'MyScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 
23:22:15,886   INFO StdSchedulerFactory:1279 - Quartz scheduler version: 1.8.3 
23:22:15,886   INFO QuartzScheduler:497 - Scheduler MyScheduler_$_1 started. 
23:22:20,018   INFO TestJob:26 - running job! 1 
23:22:50,004   INFO TestJob:26 - running job! 2 
23:22:50,010   INFO TestJob:26 - running job! 3 
23:22:50,014   INFO TestJob:26 - running job! 4 
23:22:50,016   INFO TestJob:26 - running job! 5 
... 
23:22:50,999   INFO TestJob:26 - running job! 672 
23:22:51,000   INFO TestJob:26 - running job! 673 

お知らせ:どんなに私は何をすべきか、これは私が(私はlog4jのを使用しています)を取得出力されません。この時点で、ジョブは50秒ごとに実行されるように再スケジュールされます。次回の実行時(23:22:50,004)には、何百回もスケジュールされます。

ジョブを設定する方法に関するアイデアそのジョブを実行していますか?私は間違って何をしていますか?

ありがとうございます!

答えて

5

簡単。

まず、Cron Expressionsに関する誤解がいくつかあります。 "*/20 * * * *?"コメントが意味するように20秒ごとですが、60は60で均等に割り切れるからです。 "/50 ..."は50秒ごとではありません。毎分0秒と50秒です。もう1つの例として、 "/13 ..."は毎分の秒0,13,26,39、および52です。したがって、秒52と次の分0秒の間には、13秒ではなくわずか8秒です。 */50発砲の間に50秒、他の発射の間に10秒間かかるでしょう。

しかし、それはあなたの急速な仕事の発砲の原因ではありません。問題は、現在の秒が「50」であり、新しいトリガーが2番目の「50」で起動するようにスケジューリングしているため、すぐに起動します。そしてそれはまだ秒50であり、ジョブは再び実行され、50秒間に何回もできるように、次のトリガーが2番目のトリガーに発射するようにスケジューリングします。

トリガーの開始時刻を将来(少なくとも1秒)に設定する必要があります。スケジュールが現在の秒と一致する場合は、スケジュールしている秒で起動します。

また、「N」秒のタイプのスケジュールが本当に必要な場合は、CronTriggerではなくSimpleTriggerをお勧めします。 SimpleTriggerは「35秒ごとに」または「50秒ごとに」問題なく動作します。 CronTriggerは、「1月の毎週月曜日の10時15分45秒の0,15,40および43秒」というような表現を意味します。

+0

は意味があります。テストアプリのコードを変更しました。これで、私は期待通りに動作しています...ありがとう – chahuistle

関連する問題