Post on 11-Jun-2015
description
Java Batch 1.0 – Der neue Standard für‘s Stapeln
Java Expertenkreis, 08.05.2014 Gedoplan IT Training
Klaus Bertelt, GEDOPLAN GmbH
Batch? Ein alter Hut!
Warum ist das jetzt so besonders? Ich mach das schon ewig!
Stimmt wohl, aber:
Bis jetzt ohne StandardIrgendwieOhne Unterstützung seitens des Servers
Mit Java-Batch in der Java EE 7 wird das anders!
2
Was ist Java - Batch
Neues Framework seit Java EE 7Stark inspiriert von Spring (Zusammenarbeit)Bietet standardisierte und serverseitige Unterstützung
ParallelisierbarStatusgesteuertEntscheidungsgesteuertSteuerung via XML oder Artefakten
Menge von Interfaces, die mit der entsprechenden Funktionalität implementiert werden könnenEE oder standalone
3
Wann nutze ich (Java) – Batch?
Batch –Kandidaten sind:
immer wiederkehrende Prozessezeit-, rechen-, oder speicherintensivohne menschliche Beteiligungklar definierbar (einzelne Schritte)
Bsp: Tägliche Aktualisierung eines Artikelstamms
4
Batch – grundlegende Begriffe
JobList: Oberstruktur im Batchprocessing. Besteht aus 1-n Jobs.Job: Bestandteil der Joblist. Kann mit anderen Jobs in Beziehung gesetzt werden. Ein Job besteht aus 1-n StepsStep: Bestandteil eines Jobs. Beinhaltet einzelne Arbeitsschritte, Chunk (Brocken, Batzen): die eigentlichen Arbeitstiere. Chunk und E.V.A. sind gute FreundeTask (Batchlet): Zuarbeiter, nicht zwangs-
läufig laufzeitintensiv.
5
Batch - grundlegende Begriffe
Flow: Abfolge von Steps, die als Einheit ausgeführt werden können.Split: Menge von Flows, die parallel ausgeführt werden können.Decision: Entscheider, z. Bsp. ob nächster Step ausgeführt wird, oder der Job terminiert wird.Partition: Möglichkeit, Batch-Mengen auf mehr als einem Thread laufen zu lassen.Checkpoint: Wird gesetzt, wenn die Ergebnisse eines Chunks übergeben wurden; Ermöglicht so das genau Ansteuern von Teilaufgaben
Für mehr Infos: http://download.oracle.com/otndocs/jcp/batch-1_0-fr-spec/
6
Batch - Struktur
JobOperator: Manager des JobsJobRepository: Enthält Infos über Jobs, die laufen oder gelaufen sind.
7
Quelle: JSR-352-1.0-Final-Release.pdf
Implementierung - Steuerdatei
In Enterprise-Applications
In Web-Applications
8
Naming: *jobID*.xml
Implementierung – So sieht sie aus:
9
<job id="adressJob" xmlns=http://xmlns.jcp.org/xml/ns/javaee” version="1.0"> <listeners> <listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyJobListener"/> </listeners> <step id="buildingData" next="adressStep"> <batchlet ref="de.gedoplan.seminar.javabatch.batch.GenerateDataBatchlet" /> </step> <step id="adressStep"> <listeners> <listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyStepListener"/> </listeners> <chunk item-count="10"> <reader ref="adressItemReader" /> <processor ref="adressItemProcessor" /> <writer ref="adressItemWriter" /> </chunk> </step></job>
Implementierung - BatchletTask:
Wird einmal im Step ausgeführt.
10
Job.xml:
<step id="buildingData" next="adressStep"><batchlet ref="de.gedoplan.seminar.javabatch.batch.GenerateDataBatchlet" /></step>
Implementierung:
public class GenerateDataBatchlet implements Batchlet {
@Overridepublic String process() throws Exception {return null;}
@Overridepublic void stop() throws Exception {}
Implementierung – Chunk
Chunk:Wird solange wiederholt, wie Daten vorhanden sind.
11
Job.xml:
<chunk item-count="10"> <reader ref="adressItemReader" /><processor ref="adressItemProcessor" /><writer ref="adressItemWriter" /></chunk>
1.
2.
„count“ -mal
„count“ -mal
Writer
ItemReaderItemProcessor
Implementierung – Chunk: ItemReader
Wird pro Operation (z. Bsp. Datensatz) einmal ausgeführt
12
@Namedpublic class AdressItemReader implements ItemReader {
@Overridepublic void open(Serializable checkpoint) throws Exception {}
@Overridepublic String readItem() throws Exception {return null;}
@Overridepublic Serializable checkpointInfo() throws Exception {return null;}
@Overridepublic void close() throws Exception {}
Implementierung – Chunk: ItemProcessor & ItemWriter
Wird pro Operation (z. Bsp. Datensatz) einmal ausgeführt
Wird 1 mal alle „item-counts“ ausgeführt
13
@Namedpublic class AdressItemProcessor implements ItemProcessor {
@Overridepublic Person processItem(Object arg0) throws Exception {return null;}
@Namedpublic class AdressItemWriter implements ItemWriter {
@Overridepublic void writeItems(List<Object> arg0) throws Exception {}
@Overridepublic Serializable checkpointInfo()throws Exception {return null;}
@Overridepublic void open(Serializable checkpoint) throws Exception {}
@OverridePublic void close()throws Exception {}
Implementierung - Properties
Möglichkeit 1: Übergabe bei Batch-StartJava.util.Properties erzeugenfüllenmitgeben
Möglichkeit 2: Auf nahezu jeder Ebene des job.xml können properties definiert werden:
14
<job id=„adressJob"> <properties> <property name=„adressFile" value=„adressen.txt" /> </properties> <step id=„step1"> <chunk> <properties> <property name=„adressFile" value="#{jobProperties[‚adressfile']}" /> </properties>
- jobParameters
- jopProperties- systemProper
ties- partitionPlan@Inject
@BatchProperty(name = „adressFile")private String filename;
Implementierung - CheckPoint
Optional, aber:Hilft bei Fehlern nicht komplett wieder von Vorn zu starten
Beispiel: 1.000.000 Zeilen einlesen, Zeile 999.000 führt zu einem Fehler.
Möglichkeit 1:
15
<chunk checkpoint-policy="item" commit-interval="10" item-count="10">
@Overridepublic void open(Serializable checkpoint) throws Exception {
if (checkpoint == null) {this.counter = 0;} else {this.counter = (Integer) checkpoint;}
@Overridepublic Serializable checkpointInfo() throws Exception {
return 0;}
Implementierung - Checkpoint
Schicker: Checkpoint Algorithm
16
@Namedpublic class AdressCheckpointAlgorithm extends AbstractCheckpointAlgorithm {
@Overridepublic void beginCheckpoint() throws Exception {System.out.println("Etwas zum Anfang machen.");}
@Overridepublic void endCheckpoint() throws Exception {System.out.println("Etwas zum Ende machen.");}
@Overridepublic boolean isReadyToCheckpoint() throws Exception {
return AdressItemReader.COUNT % 100 == 0;}}
Job.xml: <chunk checkpoint-policy="custom"
WICHTIG:
ReaderCheckpoints
sind unabhängig
von
WriterCheckpoints
und umgekehrt!
Implementierung - Partition
Möglichkeit auf Step-Ebene Prozesse parallel auf mehreren Threads ablaufen zu lassen
17
Step
Chunk
ItemReader
ItemWriter
Chunk
ItemReader
ItemWriter
ItemProcessor
ItemProcessor
Chunk
ItemReader
ItemWriter
ItemProcessor
Implementierung – Partitioning
Entweder PartitionPlan
Oder PartitionMapper
18
<chunk>…<properties> <property name="firstItem" value="#{partitionPlan['firstItem']}"/> <property name="lastItem" value="#{partitionPlan['lastItem']}"/></properties>…</chunk>
public class MyMapper implements PartitionMapper{
@Overridepublic PartitionPlan mapPartitions() throws Exception {return null;}
public void setThreads(…)public void setPartitionsOverride(…)public void setPartitions(…)public void setPartitionProperties(…)public int getThreads()public boolean getPartitionsOverride()public int getPartitions()public Properties[] getPartitionProperties()
<partition> <mapper ref="MyPartitionMapperImpl"/> …</partition>
Job.xml:
<partition> <plan partitions="2" threads="2"> <properties partition="0"> <property name="firstItem" value="0"/> <property name="lastItem" value="500"/> </properties> <properties partition="1"> <property name="firstItem" value="501"/> <property name="lastItem" value="999"/> </properties> </plan> </partition>
Implementierung - Partitioning
Reducer: Implementierung von PartitionReducerSteuerung der Partitionen
Collector:Implementierung von PartitionCollectorSenden von Zwischenergebnissen einzelner Partitionen
Analyser:Implementierung von PartitionAnalyserAnalyse der Zwischen- und Endergebnisse
19
<partition> <reducer ref=„…“/> <collector ref=„…“/> <analyser ref=„…“/></partition>
Implementierung – Flow, Split und Decision
Kurz angerissen:Flow:
Führt Elemente als Einheit ausKann weitere Flows, Decision, Splits enthalten
Split:Führt Elemente gleichzeitig aus (jedes auf einem eigenen Thread)Kann Flows enthalten
Decision:Ermöglicht Entscheidungen bzgl. weiterer VerarbeitungKann Steps, Flows, Splits enthalten
20
Implementierung Transitions
Kurz angerissen:Transitions ermöglichen die Steuerung nach einem Step, Flow, Split oder Decision für die nächsten Schritte:
Next: Das nächste Element wird ausgeführtFail: Job endet mit Status: FAILEDEnd: Job endet mit Status: COMPLETEDStop: Job endet mit Status: STOPPED
21
<next on="{exit status}" to="{step id|flow id|split id}”/><fail on="{exit status}" exit-status="{exit status}"/>
Flow
Wie kann das aussehen?
22
Step I
Task
Step II
Chunk
ItemReader
ItemWriter
Step III
Chunk
Deci-
sion
ItemReader
ItemWriter
Step IV
Chunk
ItemReader
ItemWriter
EndeStart
ItemProcessor
ItemProcessor
ItemProcessor
Implementierung – Listener
Für weitere Operationen können auf die verschiedenen Bestandteile des Batch Listener gelegt werden:
JobJobListener
StepStepListenerItemReadListener, ItemProcessListener, ItemWriteListenerChunkListener RetryReadListener, RetryProcessListener, RetryWriteListener SkipReadListener, SkipProcessListener, SkipWriteListener
23
Implementierung – im xmlJob-Ebene
Step-Ebene
24
<step id="adressStep"><listeners><listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyStepListener"/><listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyChunkListener"/><listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyBatchletListener"/>…</listeners>
<job id="adressJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee"version="1.0"><listeners><listener ref="de.gedoplan.seminar.javabatch.batch.listener.MyJobListener"/></listeners>
Implementierung - Exceptions
1. es! passieren! keine! Fehler!!!!2. Aber, was wenn doch?
Nicht abgefangene Exceptions terminieren mit Status FAILEDVerhalten kann überschrieben werden
Retryable Exceptions: Prozess versucht‘s nochmal
25
<skippable-exception-classes> <include class="{fullpackage-classname}"/> <exclude class="{fullpackage-classname}"/></skippable-exception-classes>
Implementierung – Wie starte ist das Ganze?
Starten:
Restarten (nach Fehler, Stopp):
Wichtig: restart funktioniert nur wenn Status != COMPLETED, ABANDONED
26
JobOperator jobOperator = BatchRuntime.getJobOperator(); Properties props = new Properties(); props.setProperty("parameter1", "value1"); ... long execID = jobOperator.start("simplejob", props);
executionId = BatchRuntime.getJobOperator().restart(executionId, new Properties());
Statüsse … Stati … Statanten … Status (plural)!
STARTING: Job/Step wurde an die Batch runtime übermittelt.STARTED: Job/Step läuft.STOPPING: Job/Step hat einen entsprechenden Halt-Request. bekommen.STOPPED: Job/Step ist gestoppt.FAILED: Job/Step ist aufgrund eines Fehlers beendet. (z. Bsp. bei jeder nicht gefangenen Exception)COMPLETED: Job/Step ist erfolgreich durchgelaufen.ABANDONED: Job/Step ist beendet.
27
STOPPED
Was kann alles so passieren?
28
STARTING STARTEDCOMPLET
ED
FAILED
STOPPING
ABANDONED
stop()
start()
abandon()
abandon()
abandon()
restart()
restart()
Demo
29
LIVE -
DEMO
Monitoring – Im WildFly? Fehlanzeige
Es gibt zwar Einstellungen für Batching, aber die betreffen mehr die Thread Eigenschaften
30
Monitoring – Gott Sei Dank recht einfach selbst geschrieben
Grundlegende Möglichkeiten:JobOperator
JobExecution
StepExecution
Aus der Demo:
31
JobExecution execution = jo.getJobExecution(executionId);
List<StepExecution> steps = jo.getStepExecutions(executionId);
JobOperator jo = BatchRuntime.getJobOperator();
s.setName(se.getStepName());s.setStatus(se.getBatchStatus().toString());s.setExitStatus(se.getExitStatus());
Monitoring – Innerhalb des Batches
JobContext
StepContext
Beispiele:
32
@Injectprivate JobContext jc;
@Injectprivate StepContext sc;
sc.getBatchStatus();sc.getExitStatus();sc.setExitStatus();
Fazit
Endlich ein StandardVereinfacht viele DingeBietet viele Möglichkeiten
… die man selbst schreiben muss(Noch) wenig Infos im NetzIst neu und es gibt noch keine (nicht viel) Produktiverfahrung.
Bisherige Erfahrungen gut!ABER: Oracle, da geht noch
was!!!33
Vielen Dank für die Aufmerksamkeit!
Noch Fragen?
34