質問

Quartz Enterprise Job Scheduler(1.8.3)を使用しています。ジョブ構成はいくつかのXMLファイルからのものであり、これらのXMLファイルと再スケジュールのジョブの変更を検出する特別なジョブがあります。これはDandyに機能しますが、問題は、この「スケジューラジョブ」がそれ自体を再スケジュールするために必要なことです。このジョブがスケジュール自体を再スケジュールすると、何らかの理由で、何度も実行されることがわかります。ただし、例外はありません。

問題を複製して分離しました。これがエントリポイントになります:

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.rescheduleJobscheduler.deleteJob それから scheduler.scheduleJob. 。私が何をしても、これは私が得る出力です(私はlog4jを使用しています):

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

23:22:20,018に、ジョブが正常に実行される方法に注意してください。この時点で、ジョブは50秒ごとに走るためにスケジュール自体を再スケジュールします。次に実行されると(23:22:50,004)、何百回もスケジュールされます。

ジョブの構成方法に関するアイデア その間 その仕事を実行しますか?私は何が間違っているのですか?

ありがとう!

役に立ちましたか?

解決

簡単。

まず、Cronの表現についての誤解がいくつかあります。 「 */20 * * *?」コメントが示唆するように20秒ごとにですが、60が20で均等に割り切れるからです。」/50 ...「50秒ごとではありません。毎分0と50です。別の例として、 "/13 ... "は秒0、13、26、39、および52分の52です。したがって、2番目の52と次の1分0秒の間に、13ではなく8秒しかありません。他のすべての発砲の間に50秒、他の射撃の間で10秒を取得します。

しかし、それはあなたの仕事の急速な解雇の原因ではありません。問題は、現在の秒が「50」であり、新しいトリガーが2番目の「50」で発射するようにスケジュールしているため、すぐに発砲することです。そして、それはまだ2番目の50であり、ジョブは再び実行され、50秒間にできる限り多くの場合、2番目の50で発砲する別のトリガーをスケジュールします。

トリガーの開始時間を未来に設定する必要があります(少なくとも1秒)、スケジュールが現在の秒と一致する場合、スケジュールするのと同じ秒で発火します。

また、すべての「n」秒タイプのスケジュールが必要な場合は、crontriggerではなくSimpleTriggerをお勧めします。 SimpleTriggerは、「35秒ごとに」または「50秒ごとに」問題ありません。 Crontriggerは、「1月の毎週月曜日の10時の15分の15分、15、40、45の秒」などの表現を目的としています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top