2016-05-02 15 views
0

Hallo Frühling Batch-Benutzer,Spring Batch Neustart abgestürzt Jobs

in Bezug auf die Dokumentation http://docs.spring.io/spring-batch/reference/htmlsingle/#d5e1320

"Wenn der Prozess gestorben (" kill -9" oder Serverausfall) wird der Auftrag, natürlich, nicht ausgeführt wird, aber das JobRepository hat keine Möglichkeit zu wissen, weil niemand es gesagt hat, bevor der Prozess gestorben ist. "

Ich versuche, die abgestanden Job Hinrichtung zu finden und neu starten, indem

Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(jobName); 
... 
jobExecution.setStatus(FAILED); 
jobExecution.setEndTime(new Date()); 
jobRepository.update(jobExecution); 
jobOperator.restart(jobExecution.getId()); 

verwenden, aber dies scheint sehr unbequem zu sein. 1) Ich muss dies tun, bevor andere (neue) Jobs gestartet werden können. 2) Ich muss mehrere Instanzen von laufenden Servern behandeln, damit findRunningJobExecutions nicht den Trick machen.

können Sie finden weitere Fragen zu diesem Thema: https://jira.spring.io/browse/BATCH-2433?jql=project%20%3D%20BATCH%20AND%20status%20%3D%20Open%20ORDER%20BY%20priority%20DESC Spring Batch after JVM crash

Ich würde eine Lösung zu sehen lieben, einen „Start-up, saubere Arbeitsplätze Hörer“ zu registrieren. Dies behebt weiterhin nicht die Probleme, die von der Multi-Server-Umgebung herrühren, da Spring Batch nicht weiß, ob die von STARTED markierte JobExecution nicht auf einer anderen Instanz ausgeführt wird.

Vielen Dank für jede Beratung Alex

+0

kill -9 ist ein Szenario, in dem ein echter (und sauberer) Neustart ist nicht möglich, Springbatch konnte den aktuellen Prozessfortschritt nicht speichern, um ihn erneut zu starten –

+0

Ja, danke für deinen Kommentar. Ich weiß, dass es nicht so entworfen ist, aber es sollte mit diesem Zeug umgehen. Ich habe ein Problem erstellt https://jira.spring.io/browse/BATCH-2505?filter=-2 Es ist nicht sehr üblich, den Server so zu stürzen, aber es ist möglich für eine Produktionsumgebung und sollte in der behandelt werden sauberste Art und Weise. –

Antwort

0

Ihre Aufgabe nicht und „automatisch“ von einem kill -9 Szenario nicht wiederherstellen können soll. A kill -9 wird sehr anders behandelt als Ihre Anwendung wirft einen gefangenen Exception. Der Grund dafür ist, dass Sie effektiv den Teppich unter der Anwendung entfernt haben, ohne ihm die Möglichkeit zu geben, einen Synchronisationspunkt mit der Datenbank zu erreichen, um die notwendigen Informationen an die ExecutionContext zu senden oder den Job-/Schrittstatus zu aktualisieren. Daher bleibt der letzte Status-Touchpoint mit der Datenbank bestehen und der Job wird weiterhin STARTED aussehen.

"OK, gut", sagst du, "aber wenn ich eine andere Ausführung beginne, möchte ich, dass diese STARTED Ausführung findet, und dort weitermachen, wo sie aufgehört hat." Das Problem hier ist, dass es keinen sauberen Weg für die Anwendung gibt, einen Job, der tatsächlich ausgeführt wird, von einem zu unterscheiden, der fehlgeschlagen ist, aber die Datenbank nicht hochfahren konnte. Das Framework hier irrt richtigerweise auf der Seite der Vorsicht und verhindert, dass Sie einen Job starten, der bereits läuft, und das ist eine gute Sache.

Warum? Nehmen wir einmal an, dass Ihre Aufgabe tatsächlich noch läuft und Sie aus Versehen neu gestartet werden. Nach der Codierung beginnt das Framework hochzufahren, erkennt die Ausführung und schlägt mit der folgenden Meldung fehl: A job execution for this job is already running. Ich kann dir nicht sagen, wie oft wir dadurch gerettet wurden, weil jemand versehentlich zweimal einen Job gestartet hat!

Wenn Sie den Listener implementieren, den Sie vorschlagen, würde stattdessen die 2. Ausführung starten und Sie hätten zwei verschiedene JVMs, die die gleiche Arbeit wiederholen und möglicherweise in die gleichen Dateien/Tabellen schreiben und eine riesige Datenverwechslung verursachen das könnte unmöglich zu säubern sein.

Vertrauen Sie mir, wenn das Linux-Terminal Ihren Job tötet oder Ihr Job stirbt, weil die Verbindung zur Datenbank getrennt wurde, WÜNSCHEN Sie sich diese Ausführungszustände an, bevor Sie einen Neustart versuchen.

schließlich auf gut Glück Sie wollte eigentlich Sie Job töten, können Sie einige andere Standardmuster zum Anhalten Arbeitsplätze nutzen:

Stop via throw Exception

Stop via JobOperator.stop()

+0

Das ist eigentlich nicht wahr. Wir betreiben Produktionsumgebungen, in denen die Wiederherstellung nach einem Betriebssystemfehler (Hardware ist tot, Stromausfall) von entscheidender Bedeutung ist. – gnomie

+0

Es soll hinzugefügt werden: Natürlich muss Ihr spezifischer Job in der Lage sein, (möglicherweise in Schritten) transaktional zu wiederholen. Wir verwenden dafür die Wiederherstellung von Quartz-Jobs. – gnomie

+0

Sicher, wenn Sie einen Ad-hoc-Job "Als fehlerhaft markieren" erstellen möchten, um Job- und Schrittausführungen von STARTED/STARTING auf FAILED zu aktualisieren, und diesen Job erst dann ausführen, wenn das Betriebssystem wieder betriebsbereit ist (und vor allen anderen) Spring Batch-Anwendungen wurden gestartet), ich denke, das wäre in Ordnung. Sie können jedoch dasselbe mit Batch-Updates für 'BATCH_JOB_EXECUTION' und' BATCH_STEP_EXECUTION' erreichen. –