So lösen Sie einen geplanten Spring Batch-Job aus und stoppen ihn

Auslösen und Beenden eines geplanten Federbatch-Jobs

1. Überblick

In diesem Tutorial untersuchen und vergleichen wir verschiedene Methoden mittrigger and stop a scheduled Spring Batch job für alle erforderlichen Geschäftsfälle.

Wenn Sie eine Einführung in Spring Batch und Scheduler benötigen, lesen Sie bitte die Artikel vonSpring-Batch undSpring-Scheduler.

2. Auslösen eines geplanten Frühjahrs-Stapeljobs

Erstens haben wir eine KlasseSpringBatchScheduler, um die Zeitplanung und den Stapeljob zu konfigurieren. Eine MethodelaunchJob() wird als geplante Aufgabe registriert.

Um den geplanten Spring Batch-Job auf intuitivste Weise auszulösen, fügen wir ein bedingtes Flag hinzu, um den Job nur dann auszulösen, wenn das Flag auf true gesetzt ist:

private AtomicBoolean enabled = new AtomicBoolean(true);

private AtomicInteger batchRunCounter = new AtomicInteger(0);

@Scheduled(fixedRate = 2000)
public void launchJob() throws Exception {
    if (enabled.get()) {
        Date date = new Date();
        JobExecution jobExecution = jobLauncher()
          .run(job(), new JobParametersBuilder()
            .addDate("launchDate", date)
            .toJobParameters());
        batchRunCounter.incrementAndGet();
    }
}

// stop, start functions (changing the flag of enabled)

Die VariablebatchRunCounter wird in Integrationstests verwendet, um zu überprüfen, ob der Stapeljob gestoppt wurde.

3. Beenden Sie einen geplanten Spring Batch-Job

Mit dem obigen bedingten Flag können wir den geplanten Spring Batch-Job mit der geplanten aktiven Aufgabe auslösen.

Wenn wir den Job nicht fortsetzen müssen, können wir die geplante Aufgabe tatsächlich stoppen, um Ressourcen zu sparen.

Schauen wir uns in den nächsten beiden Unterabschnitten zwei Optionen an.

3.1. Verwenden des Scheduler-Postprozessors

Da wir eine Methode mithilfe der Annotation von@Scheduledplanen, wurde zuerst ein Bean-PostprozessorScheduledAnnotationBeanPostProcessorregistriert.

Wir können diepostProcessBeforeDestruction() explizit aufrufen, um die angegebene geplante Bean zu zerstören:

@Test
public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception {
    ScheduledAnnotationBeanPostProcessor bean = context
      .getBean(ScheduledAnnotationBeanPostProcessor.class);
    SpringBatchScheduler schedulerBean = context
      .getBean(SpringBatchScheduler.class);
    await().untilAsserted(() -> Assert.assertEquals(
      2,
      schedulerBean.getBatchRunCounter().get()));
    bean.postProcessBeforeDestruction(
      schedulerBean, "SpringBatchScheduler");
    await().atLeast(3, SECONDS);

    Assert.assertEquals(
      2,
      schedulerBean.getBatchRunCounter().get());
}

In Anbetracht mehrerer Scheduler ist es besser, einen Scheduler in seiner eigenen Klasse zu belassen, damit wir einen bestimmten Scheduler nach Bedarf stoppen können.

3.2. Abbrechen der geplantenFuture

Eine andere Möglichkeit, den Scheduler zu stoppen, besteht darin, seineFuture manuell abzubrechen.

Hier ist ein benutzerdefinierter Taskplaner zum Erfassen der Karte vonFuture:

@Bean
public TaskScheduler poolScheduler() {
    return new CustomTaskScheduler();
}

private class CustomTaskScheduler
  extends ThreadPoolTaskScheduler {

    //

    @Override
    public ScheduledFuture scheduleAtFixedRate(
      Runnable task, long period) {
        ScheduledFuture future = super
          .scheduleAtFixedRate(task, period);

        ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task;
        scheduledTasks.put(runnable.getTarget(), future);

        return future;
    }
}

Dann iterieren wir dieFuture-Map und brechen dieFuture für unseren Batch-Job-Scheduler ab:

public void cancelFutureSchedulerTasks() {
    scheduledTasks.forEach((k, v) -> {
        if (k instanceof SpringBatchScheduler) {
            v.cancel(false);
        }
    });
}

In Fällen mit mehreren Scheduler-Aufgaben können wir die Zuordnung vonFutureinnerhalb des benutzerdefinierten Scheduler-Pools beibehalten, aber die entsprechenden geplantenFuture basierend auf der Scheduler-Klasse abbrechen.

4. Fazit

In diesem kurzen Artikel haben wir drei verschiedene Möglichkeiten ausprobiert, um einen geplanten Spring Batch-Job auszulösen oder zu stoppen.

Wenn der Stapeljob neu gestartet werden muss, ist die Verwendung eines bedingten Flags zum Verwalten der Jobausführung eine flexible Lösung. Andernfalls können Sie die beiden anderen Optionen ausführen, um den Scheduler vollständig zu stoppen.

Wie üblich sind alle im Artikel verwendeten Codebeispieleover on GitHub verfügbar.