Auslösen und Stoppen eines geplanten Spring Batch-Jobs

1. Übersicht

In diesem Lernprogramm werden verschiedene Möglichkeiten zum Auslösen und Stoppen eines geplanten Spring Batch-Jobs für erforderliche Geschäftsfälle untersucht und verglichen .

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

2. Lösen Sie einen geplanten Spring Batch-Job aus

Erstens haben wir eine Klasse SpringBatchScheduler , um die Zeitplanung und den Stapeljob zu konfigurieren. Eine Methode launchJob () 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 Variable batchRunCounter 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 @Scheduled planen , wurde zuerst ein Bean- Postprozessor ScheduledAnnotationBeanPostProcessor registriert.

Wir können die postProcessBeforeDestruction () 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. Die geplante Zukunft abbrechen

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

Hier ist ein benutzerdefinierter Taskplaner zum Erfassen der zukünftigen Karte:

@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 die Future- Map und brechen die Future 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 Future- Map innerhalb des benutzerdefinierten Scheduler-Pools verwalten, aber die entsprechende geplante Future 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 wir den Stapeljob neu starten müssen, wäre die Verwendung eines bedingten Flags zum Verwalten der Jobausführung eine flexible Lösung. Andernfalls können wir den beiden anderen Optionen folgen, um den Scheduler vollständig zu stoppen.

Wie üblich sind alle im Artikel verwendeten Codebeispiele auf GitHub verfügbar.