Frage

Ich verwende Quartz Enterprise Job Scheduler (1.8.3). Die Jobkonfiguration stammt aus mehreren XML-Dateien, und wir haben einen speziellen Job, der Änderungen in diesen XML-Dateien und Re-Schedules-Jobs erkennt. Dies funktioniert Dandy, aber das Problem ist, dass ich diesen "Scheduler-Job" auch für die Wiederherstellung selbst benötige. Sobald dieser Job selbst neu platzt, sehe ich aus irgendeinem Grund, dass er viele Male ausgeführt wird. Ich sehe jedoch keine Ausnahmen.

Ich habe das Problem repliziert und isoliert. Dies wäre der Einstiegspunkt:

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);

    }
}

Und das wäre die Jobklasse:

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);
    }
}
}

Ich habe beide versucht mit scheduler.rescheduleJob und mit scheduler.deleteJob dann scheduler.scheduleJob. Egal was ich tue, dies ist die Ausgabe, die ich bekomme (ich verwende 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

Beachten Sie, wie bei 23: 22: 20.018 der Job gut läuft. Zu diesem Zeitpunkt stellt sich der Job neu auf, um alle 50 Sekunden zu laufen. Wenn es das nächste Mal läuft (23: 22: 50.004), wird es hunderte Male geplant.

Alle Ideen zur Konfiguration eines Jobs während diesen Job ausführen? Was mache ich falsch?

Vielen Dank!

War es hilfreich?

Lösung

Einfach.

Zunächst einmal haben Sie ein paar Missverständnisse über Cron -Ausdrücke. " */20 * * * *?" ist alle zwanzig Sekunden, wie der Kommentar impliziert, aber nur, weil 60 bis 20 gleichmäßig teilbar sind. "/50 ... "ist nicht alle fünfzig Sekunden. Es ist Sekunden 0 und 50 jeder Minute. Als ein weiteres Beispiel,"/13 ... "ist Sekunden 0, 13, 26, 39 und 52 von jeder Minute - also zwischen dem zweiten 52 und der nächsten Minute ist es nur 8 Sekunden, nicht 13. Also mit */50 Sie Sie Machen Sie zwischen jedem anderen Schuss 50 Sekunden und 10 Sekunden zwischen den anderen.

Das ist jedoch nicht die Ursache für Ihr schnelles Schuss des Jobs. Das Problem ist, dass die aktuelle Sekunde "50" ist und Sie den neuen Auslöser planen, um auf die zweite "50" zu schießen, sodass er sofort ausbreitet. Und dann ist es immer noch die zweite 50, und der Job wird erneut ausgeführt, und es plant einen weiteren Auslöser, um auf den zweiten 50 und so weiter zu schießen, so oft wie möglich in der 50. Sekunde.

Sie müssen die Startzeit des Abzugs in die Zukunft einstellen (mindestens eine Sekunde), oder es wird in derselben Sekunde, in der Sie ihn planen, abfeuern, wenn der Zeitplan mit der aktuellen Sekunde übereinstimmt.

Auch wenn Sie wirklich jeden "n" -Schloster -Zeitplan benötigen, schlage ich eher Simpligger als Crontrigger vor. Simpligger kann "alle 35 Sekunden" oder "alle 50 Sekunden" ohne Problem ausführen. Crontrigger ist für Ausdrücke wie "An Sekunden 0, 15, 40 und 43 Minuten 15 und 45 der 10 Uhr am Montag im Januar" gedacht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top