tutkii JSR 352: n tarjoamaa uutta eräkäsittelykykyä Java EE 7: lle.
eräkäsittelyä käytetään monilla toimialoilla tehtäviin, jotka vaihtelevat palkanlaskennasta, statement generationista, end-of-day-töistä, kuten korkojen laskemisesta ja ETL: stä (Pura, lataa ja muuta) tietovarastoon; ja paljon muuta. Tyypillisesti eräkäsittely on irtotavarapainotteista, ei—vuorovaikutteista ja pitkäkestoista – ja saattaa olla data-tai laskentaintensiivistä. Erätyöt voidaan suorittaa aikataulussa tai aloittaa pyynnöstä. Myös, koska erätyöt ovat tyypillisesti pitkäkestoisia töitä, check-pointing ja uudelleenkäynnistys ovat yhteisiä piirteitä löytyy erätöitä.
JSR 352 (Batch Processing for Java Platform), joka on osa äskettäin esitettyä Java EE 7-alustaa, määrittelee ohjelmointimallin eräsovelluksille sekä ajoajan erätöiden suorittamiseen ja hallintaan. Tässä artikkelissa käsitellään joitakin keskeisiä käsitteitä, kuten ominaisuus kohokohtia, katsaus valittujen API, rakenne työn määritys kieli, ja näyte erän sovellus. Artikkelissa kuvataan myös, miten voit suorittaa erän sovelluksia käyttäen GlassFish Server Open Source Edition 4.0.
Eräajoarkkitehtuuri
tässä jaksossa ja Kuvassa 1 kuvataan eräajoarkkitehtuurin peruskomponentit.
kuva 1
- a työ kiteyttää koko eräprosessin. Työ sisältää yhden tai useamman vaiheen. Työ kootaan käyttämällä Job Specification Language (JSL), joka määrittää järjestyksessä, jossa vaiheet on suoritettava. JSR 352: ssa JSL määritellään XML-tiedostossa, jota kutsutaan job XML-tiedostoksi. Lyhyesti sanottuna työ (JSR 352: n kanssa) on periaatteessa säiliö askelille.
- askel on toimialueen olio, joka kiteyttää työn itsenäisen, peräkkäisen vaiheen. Vaihe sisältää kaikki tarvittavat logiikka ja tiedot suorittaa todellinen käsittely. Eräspesifikaatio jättää tarkoituksella askeleen määritelmän epämääräiseksi, koska vaiheen sisältö on puhtaasti sovelluskohtainen ja voi olla niin monimutkainen tai yksinkertainen kuin kehittäjä haluaa. Askelia on kahdenlaisia: kimpale ja batchlet.
- lohkotyylinen vaihe sisältää tasan yhden
ItemReader
, yhdenItemProcessor
ja yhdenItemWriter
. Tässä kuviossaItemReader
lukee yhden kohteen kerrallaan,ItemProcessor
käsittelee kohteen liiketoimintalogiikan perusteella (kuten” laske tilin saldo”) ja luovuttaa sen eräajolle aggregoitavaksi. Kun ”chunk-size” – kappalemäärä on luettu ja käsitelty, ne annetaanItemWriter
, joka kirjoittaa tiedot (esimerkiksi tietokantataulukkoon tai litteään tiedostoon). Tämän jälkeen kauppa tehdään. - JSR 352 määrittelee myös roll-your-omanlaisensa askeleen, jota kutsutaan lepakoksi. Batchlet on vapaa käyttämään mitä tahansa suorittaa askeleen, kuten lähettämällä sähköpostia.
- lohkotyylinen vaihe sisältää tasan yhden
-
JobOperator
tarjoaa käyttöliittymän, jolla voi hallita kaikkia työn käsittelyn osa-alueita, mukaan lukien toimintakomennot, kuten käynnistys -, uudelleenkäynnistys-ja pysäytyskomennot, sekä työvaraston komennot, kuten työn ja askelteloitusten nouto. LisätietojaJobOperator
, KS.JSR 352-eritelmän kohta 10.4. -
JobRepository
sisältää tietoa nykyisin käynnissä olevista ja aiemmin jatkuneista työpaikoista.JobOperator
tarjoaa sovellusliittymiä tämän arkiston käyttöön.JobRepository
voitiin toteuttaa vaikkapa tietokantaa tai tiedostojärjestelmää käyttäen.
yksinkertaisen Palkanlaskentasovelluksen kehittäminen
tässä artikkelissa esitellään joitakin JSR 352: n keskeisiä ominaisuuksia yksinkertaisen palkanlaskentasovelluksen avulla. Sovellus on tarkoituksella pidetty melko yksinkertaisena, jotta voidaan keskittyä JSR 352: n keskeisiin käsitteisiin.
SimplePayrollJob
erätyössä luetaan palkanlaskennan syöttötiedot pilkulla erotellusta arvoista (CSV)-tiedostosta. Jokainen rivi tiedoston sisältää työntekijän tunnus ja peruspalkka (kuukaudessa) yhden työntekijän. Tämän jälkeen erätyö laskee ennakonpidätettävän veron, bonuksen ja nettopalkan. Työ tarvitsee lopulta kirjoittaa käsitellyt palkkatiedot tietokantataulukkoon.
käytämme CSV-tiedostoa tässä esimerkissä vain osoittaaksemme, että JSR 352 mahdollistaa eräsovellusten lukemisen ja kirjoittamisen mistä tahansa mielivaltaisesta lähteestä.
työn Määrittelykieli palkkahallinnon Käsittelysovellukselle
keskustelimme siitä, että askel on toimialueen objekti, joka kiteyttää itsenäisen, peräkkäisen vaiheen työstä, ja työ on periaatteessa säiliö yhdelle tai useammalle vaiheelle.
JSR 352: ssa JSL periaatteessa määrittää, missä järjestyksessä vaiheet on suoritettava tehtävän suorittamiseksi. JSL on tarpeeksi tehokas mahdollistamaan ehdollisen suorittamisen vaiheet, ja se mahdollistaa myös jokaisen vaiheen on omat ominaisuudet, kuuntelijat, ja niin edelleen.
eräsovelluksessa voi olla niin monta JSLs: ää kuin haluaa, jolloin se voi aloittaa niin monta erätyötä kuin tarvitaan. Esimerkiksi hakemuksessa voi olla kaksi JSLs: ää, toinen palkanlaskentaan ja toinen raportin laatimiseen. Jokainen JSL on nimettävä yksikäsitteisesti ja se on sijoitettava META-INF/batch-jobs
hakemistoon. Alihakemistoja META-INF/batch-jobs
ei oteta huomioon.
meidän JSL palkanlaskentaa varten on sijoitettu tiedostoon SimplePayrollJob.xm
l ja näyttää Listaukselta 1:
<job xmlns=http://xmlns.jcp.org/xml/ns/javaee version="1.0"> <step> <chunk item-count="2"> <reader ref="simpleItemReader/> <processor ref="simpleItemProcessor/> <writer ref="simpleItemWriter/> </chunk> </step></job>
listaus 1
meidän SimplePayrollJob
erätyössä on vain yksi vaihe (ns. Se on lohkotyylinen askel ja siinä on (lohkotyylisen askeleen vaatimana) ItemReader
ItemProcessor
ja ItemWriter
ItemReader
ItemProcessor
ja ItemWriter
tämän vaiheen toteutukset on määritelty käyttämällä ref
attribuuttia <reader>
<processor>
, ja <writer>
Elements.
kun työ on lähetetty (näemme myöhemmin, miten lähetät erätöitä), eräajo alkaa JSL: n ensimmäisestä vaiheesta ja kulkee tiensä läpi, kunnes koko työ on valmis tai yksi vaihe epäonnistuu. JSL on tarpeeksi tehokas mahdollistamaan sekä ehdolliset vaiheet että rinnakkaiset vaiheet, mutta emme kata näitä yksityiskohtia tässä artikkelissa.
item-count
attribuutti, joka on määritelty 2
listauksessa 1, määrittelee lohkon koon.
tässä on korkean tason katsaus siihen, miten chunk-tyyliset askeleet toteutetaan. Lisätietoja on JSR 352-eritelmän kohdassa 11.6 (”säännöllinen Kappaleenkäsittely”).
- Aloita kauppa.
- kutsuu
ItemReader
ja siirtääItemReader
lukemansa kohteenItemProcessor
ItemProcessor
käsittelee kohteen ja palauttaa käsitellyn kohteen eräajoon. - eräajo toistaa vaiheen 2
item-count
kertaa ja ylläpitää luetteloa käsitellyistä eristä. - erän juoksuaika laskee
ItemWriter
, joka kirjoittaaitem-count
käsiteltyjen erien määrän. - Jos poikkeuksia heitetään
ItemReader
ItemProcessor
taiItemWriter
, tapahtuma epäonnistuu ja vaihe merkitään ”epäonnistui.”KS.JSR 352-eritelmän 5.2.1.2.1 kohta (poikkeusten ohittaminen). - Jos poikkeuksia ei ole, erän suoritusaika saa tarkastuspistetiedot
ItemReader
jaItemWriter
(lisätietoja JSR 352-spesifikaation kohdassa 2.5). Erän suoritusaika toimittaa tapahtuman. - vaiheet 1-6 toistetaan, jos
ItemReader
on enemmän tietoa luettavana.
tämä tarkoittaa, että esimerkissämme eräajoaika lukee ja käsittelee kaksi tietuetta ja ItemWriter
kirjoittaa kaksi tietuetta per tapahtuma.
kirjoittaa ItemReader
ItemProcessor
, ja ItemWriter
kirjoittaa ItemReader
palkkakäsittelyn erän JSL määrittelee yhden kimpaleen tyylinen vaihe ja määrittää, että askel käyttää ItemReader
nimettyä simpleItemReader
. Sovelluksessamme on toteutus ItemReader
input CSV-tietojen lukemiseksi. Listaus 2 näyttää pätkän meidän ItemReader
:
@Namedpublic class SimpleItemReader extends AbstractItemReader { @Inject private JobContext jobContext; ...}
listaus 2
huomaa, että luokkaan on liitetty huomautus @Named
huomautus. Koska @Named
annotation käyttää oletusarvoa, tämän pavun Contexts and dependence Injection (CDI) – nimi on simpleItemReader
. JSL määrittää ItemReader
<reader>
– elementin CDI-nimen. Näin eräajoaika voi instantioida (CDI: n kautta) meidän ItemReader
kun vaihe suoritetaan.
meidän ItemReader
myös JobContext
JobContext
antaa eräesineen (ItemReader
, tässä tapauksessa) lukea arvoja, jotka on ohitettu työn jättämisen aikana.
palkanlaskentamme SimpleItemReader
ohittaa open()
menetelmän avata syöttö, josta palkanlaskentatiedot luetaan. Kuten myöhemmin nähdään, parametri prevCheckpointInf
o ei ole nolla, jos työ aloitetaan uudelleen.
esimerkissämme open()
menetelmä, joka näkyy listauksessa 3, Avaa palkanlaskentatiedoston (joka on paketoitu hakemuksen mukana).
public void open(Serializable prevCheckpointInfo) throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); Properties jobParameters = jobOperator.getParameters(jobContext.getExecutionId()); String resourceName = (String) jobParameters.get("payrollInputDataFileName"); inputStream = new FileInputStream(resourceName); br = new BufferedReader(new InputStreamReader(inputStream)); if (prevCheckpointInfo != null) recordNumber = (Integer) prevCheckpointInfo; for (int i=1; i<recordNumber; i++) { //Skip upto recordNumber br.readLine(); } System.out.println(" Opened Payroll file for reading from record number: " + recordNumber); }
listaus 3
readItem()
menetelmä käytännössä lukee yhden rivin tietoja syöttötiedostosta ja määrittää, sisältääkö rivi kaksi kokonaislukua (yksi työntekijän ID: lle ja yksi peruspalkalle). Jos kokonaislukuja on kaksi, se luo ja palauttaa uuden esiintymän PayrollInputRecord
ja palaa eräajoon (joka sitten siirtyy ItemWriter
).
public Object readItem() throws Exception { Object record = null; if (line != null) { String fields = line.split("+"); PayrollInputRecord payrollInputRecord = new PayrollInputRecord(); payrollInputRecord.setId(Integer.parseInt(fields)); payrollInputRecord.setBaseSalary(Integer.parseInt(fields)); record = payrollInputRecord; //Now that we could successfully read, Increment the record number recordNumber++; } return record;}
listaus 4
menetelmää checkpointInfo()
kutsutaan erän suoritusajan mukaan jokaisen onnistuneen kimpaletapahtuman lopussa. Näin lukija voi tarkistaa pisteen viimeisen onnistuneen lukuasennon.
esimerkissämme checkpointInfo()
palauttaa recordNumber
osoittaen onnistuneesti luettujen tietueiden määrän, kuten listaus 5 osoittaa.
@Overridepublic Serializable checkpointInfo() throws Exception { return recordNumber;}
listaus 5
kirjoittaminen ItemProcessor
meidän SimpleItemProcessor
noudattaa samanlaista kaavaa kuin SimpleItemReader
.
processItem()
menetelmä saa (eräajosta) PayrollInputRecord
. Sen jälkeen se laskee veron ja nettoarvon ja palauttaa PayrollRecord
tuotokseksi. Huomaa listauksessa 6, että ItemProcessor
palauttama objektityyppi voi olla hyvin erilainen kuin ItemReader
.
@Namedpublic class SimpleItemProcessor implements ItemProcessor { @Inject private JobContext jobContext; public Object processItem(Object obj) throws Exception { PayrollInputRecord inputRecord = (PayrollInputRecord) obj; PayrollRecord payrollRecord = new PayrollRecord(); int base = inputRecord.getBaseSalary(); float tax = base * 27 / 100.0f; float bonus = base * 15 / 100.0f; payrollRecord.setEmpID(inputRecord.getId()); payrollRecord.setBase(base); payrollRecord.setTax(tax); payrollRecord.setBonus(bonus); payrollRecord.setNet(base + bonus - tax); return payrollRecord; } }
listaus 6
kirjoittaminen ItemWriter
tähän mennessä, SimpleItemWriter
on noudatettava sinulle ennustettavia rivejä.
ainoa ero on se, että se pistää EntityManager
niin, että se voi säilyttää PayrollRecord
esiintymät (jotka ovat yhteisen parlamentaarisen edustajakokouksen yhteisöjä) tietokantaan, kuten listaus 7 osoittaa.
@Namedpublic class SimpleItemWriter extends AbstractItemWriter { @PersistenceContext EntityManager em; public void writeItems(List list) throws Exception { for (Object obj : list) { System.out.println("PayrollRecord: " + obj); em.persist(obj); } }}
listaamalla 7
writeItems()
menetelmä säilyttää kaikkiPayrollRecord
esiintymät TIETOKANTATAULUKKOON yhteisen parlamentaarisen edustajakokouksen avulla. Luettelossa on korkeintaanitem-count
merkinnät (kimpaleen koko).
nyt kun meillä on JSL, ItemReader
ItemProcessor
, ja ItemWriter
valmiina, katsotaan miten erätyö saadaan lähetettyä.
erätyön aloittaminen Servletistä
huomaa, että pelkkä työn XML-tiedoston tai muiden eräesineiden (kuten ItemReader
) läsnäolo ei tarkoita, että erätyö käynnistyy automaattisesti, kun sovellus otetaan käyttöön. Erätyö on käynnistettävä nimenomaisesti esimerkiksi servletistä tai Enterprise JavaBeans (EJB) – ajastimesta tai EJB-liiketoimintamenetelmästä.
palkkahakemuksessamme käytämme erätyön lähettämiseen servletiä (nimeltään PayrollJobSubmitterServlet
). Servlet näyttää HTML-sivun, joka esittää käyttäjälle lomakkeen, joka sisältää kaksi painiketta. Kun ensimmäistä painiketta, jonka nimi on Calculate Payroll, napsautetaan, servlet käyttää startNewBatchJob
– menetelmää, joka on esitetty listauksessa 8, joka aloittaa uuden erätyön.
private long startNewBatchJob()throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); Properties props = new Properties(); props.setProperty("payrollInputDataFileName", payrollInputDataFileName); return jobOperator.start(JOB_NAME, props);}
listaus 8
ensimmäinen askel on saada esiintymä JobOperator
. Tämä voidaan tehdä soittamalla seuraavat:
JobOperator jobOperator = BatchRuntime.getJobOperator();
servlet luo sitten Properties
objektin ja tallentaa syötetiedoston nimen siihen. Lopuksi aloitetaan uusi erätyö kutsumalla:
jobOperator.start(jobName, properties)
jobname
ei ole muuta kuin työn JSL XML-tiedostonimi (miinus .xml
laajennus). properties
parametri välittää kaikki syötetiedot työhön. Properties
objekti (joka sisältää palkanlaskutiedoston nimen) annetaan muiden eräesineiden (kuten ItemReader
ItemProcessor
ja niin edelleen) käyttöön JobContext
– rajapinnan kautta.
erän suoritusaika antaa yksilöllisen tunnisteen, jota kutsutaan suoritustunnisteeksi, joka tunnistaa jokaisen suorituksen, onko kyseessä juuri lähetetty vai uudelleen käynnistetty työ. Monet JobOperator
menetelmät ottavat suoritustunnuksen parametrina. Suoritustunnuksen avulla ohjelma voi saada nykyisen (ja menneen) suoritustilan ja muita tilastoja työstä. JobOperator.start()
menetelmä palauttaa aloitetun työn suoritustunnuksen.
noudetaan tietoja Erätöistä
kun erätyö lähetetään, eräajoaika Luo JobExecution
sen seuraamiseksi. JobExecution
on menetelmiä, joilla saadaan erilaisia yksityiskohtia, kuten työn alkamisaika, työn valmistumisaika, työn poistumistila ja niin edelleen. JobExecution
suoritustunnuksen saamiseksi voi käyttää JobOperator.getJobExecution(executionId)
– menetelmää. Listaus 9 osoittaa JobExecution
:
package javax.batch.runtime;public interface JobExecution { long getExecutionId(); java.lang.String getJobName(); javax.batch.runtime.BatchStatus getBatchStatus(); java.util.Date getStartTime(); java.util.Date getEndTime(); java.lang.String getExitStatus(); java.util.Date getCreateTime(); java.util.Date getLastUpdatedTime(); java.util.Properties getJobParameters();}
listaus 9
hakemuksen pakkaaminen
nyt kun meillä on JSL, ItemReader
ItemProcessor
ItemWriter
, ja meidän Servlet valmiina, on aika pakata ne ja valmistautua käyttöönottoon.
voit ottaa eräsovelluksesi käyttöön minkä tahansa tuetun Java EE-arkiston muodossa (esimerkiksi .war
.jar
tai .ear
). Voit niputtaa erän artefakti luokat yhdessä muiden Java EE luokat (kuten EJB pavut ja servlets).
ainoa erityisvaatimus on, että työpaikkajulkaisut on sijoitettava META-INF/batch-jobs
hakemistoon .jar
files. Jos .war
arkistotyypit, aseta työpaikkasi JSLs alle WEB-INF/classes/META-INF/batch-jobs
hakemistoon.
Palkkanäytesovelluksen käyttöönotto ja käyttö GlassFish 4.0
otetaan käyttöön palkkanäytesovellus, jonka olemme kehittäneet GlassFish 4.0-sovelluspalvelimeksi. Glassfish 4.0 on Java EE 7.0-spesifikaation referenssitoteutus (ri) ja sisältää myös JSR 352: n RI: n. Lisää tietoa GlassFish 4.0: sta löydät osoitteesta http://glassfish.org ja Javan erästä 1.0 ri osoitteesta https://javaee.github.io/.
Glassfish 4.0: n asentaminen ja käynnistäminen
voit ladata GlassFish 4.0: n osoitteesta https://glassfish.java.net/download.html ja asentaa sen sitten. Käynnistä GlassFish 4.0 avaamalla komentoikkuna ja ajamalla seuraava komento:
<GlassFish Install Dir>/bin/asadmin start-domain
koska näytepalkkasovellus käyttää tietokantaa (prosessoitujen tietojen kirjoittamiseen), tarvitsemme tietokannan suoritettavaksi ennen kuin voimme suorittaa sovelluksemme. Apache Derby-tietokannan voi käynnistää suorittamalla seuraavan komennon:
<GlassFish Install Dir>/bin/asadmin start-database
kootaan, paketoidaan ja otetaan käyttöön Palkkasovellus
ensin luodaan uusi hakemisto, jonka nimi on hello-batch
. Vaihda sitten hello-batch
hakemistoon:
cd hello-batch
kääntääksesi ja paketoidaksesi suorita seuraava komento, joka Luo hello-batch.war
kohdehakemiston alla:
mvn clean package
ottaaksesi käyttöön hello-batch.war
, suorita seuraava komento:
<GlassFish Install Dir>/bin/asadmin deploy target/hello-batch.war
Jos haluat siirtää sovellusta, voit suorittaa seuraavan komennon:
<GlassFish Install Dir>/bin/asadmin deploy -force target/hello-batch.war
Palkanlaskentasovelluksen ajaminen
kun otat hello-batch.war
– tiedoston käyttöön, voit suorittaa sovelluksen avaamalla http://localhost:8080/hello-batch/PayrollJobSubmitterServlet
selaimesta. Tämän URL-osoitteen pitäisi näyttää kuvassa 2 esitetty näyttö.
kuva 2
klikkaa Laske palkanlaskenta-painiketta ja näet uuden merkinnän taulukossa, kuten kuvassa 3.
kuva 3
Napsauta Päivitä-painiketta ja näet viimeisimmän työn Poistumistila-ja päättymisaika-sarakkeet päivitettyinä (KS.Kuva 4). Exit Status-sarake näyttää, onko työ epäonnistunut vai suoritettu onnistuneesti. Koska meidän SimplePayrollJob
ei ole virheitä (ainakaan vielä!), Poistumistilanäytöt suoritettu.
kuva 4
napsauta Laske palkanlaskenta-ja päivitä-painikkeita vielä muutaman kerran. Huomaa, että joka kerta kun työ aloitetaan, työlle annetaan uusi suoritustunnus (ja instanssitunnus), kuten kuvassa 5 esitetään.
kuva 5
epäonnistuneiden töiden uudelleenkäynnistäminen
tähän mennessä olimme aloittaneet erätöitä jobOperator.start()
– menetelmällä. Sanotaan, että meidän palkkatiedoston on joitakin virheitä. Joko ItemReader
tai ItemProcessor
voivat havaita virheelliset tietueet ja epäonnistua nykyisessä vaiheessa ja tehtävässä. Järjestelmänvalvoja tai loppukäyttäjä voi korjata virheen ja voi käynnistää erän työtä. Tämä lähestymistapa käynnistää uuden työn, joka alkaa alusta jälkeen toipuminen virheistä ei välttämättä mittakaavassa, jos määrä tietoja on suuri. JobOperator
tarjoaa toisen restart()
– nimisen menetelmän juuri tämän ongelman ratkaisemiseksi.
pikakatsauksen JobInstance
ja JobExecution
näimme aiemmin, että työ on pohjimmiltaan askelten säiliö. Kun työ aloitetaan, sitä on seurattava, jolloin eräajoaika Luo JobInstance
JobInstance
viittaa loogisen ajon käsitteeseen. Esimerkissämme on PayrollJob
ja jos PayrollJob
ajetaan joka kuukausi, tulee olemaan Tammi-2013 JobInstance
ja tulee toinen helmi-2013 JobInstance
ja niin edelleen.
Jos Tammi-2013 palkanlaskennan käsittely epäonnistuu, se on käynnistettävä uudelleen (oletettavasti virheen korjaamisen jälkeen), mutta se on edelleen Tammi-2013-suoritus, koska se käsittelee edelleen Tammi-2013-tietoja.
a JobExecution
viittaa käsitteeseen, jonka mukaan työtä yritetään suorittaa vain kerran. Joka kerta kun työt aloitetaan tai aloitetaan uudelleen, luodaan uusi JobExecution
, joka kuuluu samaan JobInstance
. Esimerkissämme, jos Tammi-2013 JobInstance
käynnistetään uudelleen, se on edelleen sama Tammi-2013 JobInstance
mutta syntyy uusi JobExecution
, joka kuuluu samaan JobInstance
div>.
tiivistettynä työssä voi olla yksi tai useampi esiintymä JobInstance
ja jokaisessa JobInstance
voi olla yksi tai useampi JobExecution
esiintymä. Käyttämällä uutta JobInstance
tarkoittaa ”aloita alusta” ja käyttämällä olemassa olevaa JobInstance
tarkoittaa yleensä ”aloita siitä, mihin jäit.”
epäonnistuneiden töiden jatkaminen
Jos muistat, lohkotyylinen vaihe suorittaa tapahtuman, jossa item-count
merkinnät luetaan, käsitellään ja kirjoitetaan. Kun ItemWriter
’s writeItems()
on vedottu, eräajo kutsuu checkpointInfo()
menetelmää sekä ItemReader
että ItemWriter
. Näin sekä ItemReader
että ItemWriter
voivat merkitä (tallentaa) nykyisen edistymisensä. ItemReader
bookmarked data voi olla mitä tahansa, joka auttaa sitä jatkamaan lukemista. Esimerkiksi SimpleItemReader
tarvitsee tallentaa rivinumero, johon asti se on tähän mennessä lukenut onnistuneesti.
JSR 352-spesifikaation kohdassa 10.8 kuvataan uudelleenkäynnistyskäsittelyä yksityiskohtaisesti.
katsotaan hetki lokitiedostoa, jossa SimpleItemReader
tuottaa joitakin hyödyllisiä viestejä open()
ja checkpoint()
metodeista. Jokaisen viestin etuliitteenä on merkkijono , joten viestit voi tunnistaa nopeasti. Lokitiedosto sijaitsee osoitteessa
<GlassFish install Dir>/domains/domain1/logs/server.log
.
listaus 10 näyttää viestit, joiden etuliitteenä on merkkijono :
Opened Payroll File. Will start reading from record number: 0]] checkpointInfo() called. Returning current recordNumber: 2]] checkpointInfo() called. Returning current recordNumber: 4]] checkpointInfo() called. Returning current recordNumber: 6]] checkpointInfo() called. Returning current recordNumber: 8]] checkpointInfo() called. Returning current recordNumber: 9]] close called.]]
listaus 10
HUOM: Voit käyttää myös komentoa tail -f server.log | grep SimpleItemReader
.
koska, meidän tehtävämme XML-tiedosto (SimplePayrollJob.xml
) määrittää arvon 2
item-count
lohkokoon, erän runtime kutsuu checkpointInfo()
meidän ItemReader
joka toinen levy. Eräajo tallentaa tämän tarkastuspisteen tiedot JobRepository
. Joten, jos virhe tapahtuu keskellä meidän kimpale käsittely, erän sovellus on voitava jatkaa viime onnistunut checkpoint.
otetaan käyttöön joitakin virheitä syöttötiedostossamme ja katsotaan, miten voimme toipua syöttövirheistä.
Jos katsot servletimme tulostetta, joka sijaitsee alla <GlassFish install Dir>/domains/domain1/applications/hello-batch/WEB-INF/classes/payroll-data/payroll-data.csv
, näet, että se näyttää sen syötetiedoston sijainnin, josta CSV-tiedot luetaan palkkasovellustamme varten. Listaus 11 näyttää tiedoston sisällön:
1, 81002, 82003, 83004, 84005, 85006, 86007, 87008, 88009, 8900
listaus 11
avaa suosikkieditorisi ja tuo virhe. Esimerkiksi sanotaan, että lisäämme palkkakenttään muutaman merkin kahdeksannella levyllä, kuten listaus 12 osoittaa:
1, 81002, 82003, 83004, 84005, 85006, 86007, 87008, abc88009, 8900
listaus 12
Tallenna tiedosto ja lopeta muokkain. Palaa selaimeesi ja napsauta Laske Palkkahinta-painiketta ja Päivitä-painiketta. Näet, että äskettäin jätetty työ epäonnistui, kuten kuvassa 6. (Katso Exit Status-saraketta.)
kuva 6
huomaat myös, että juuri epäonnistuneen työn suoritustunnuksen vieressä on Uudelleenkäynnistyspainike. Jos napsautat Päivitä, työ epäonnistuu (koska emme ole korjanneet ongelmaa vielä). Kuva 7 näyttää, mitä näytetään muutaman päivityspainikkeen napsautuksen jälkeen.
kuva 7
Jos tarkastelet Glassfishin palvelinlokia (sijaitsee alla <GlassFish install Dir>/domains/domain1/logs/server.log
), näet poikkeuksen, kuten listaus 13:
Caught exception executing step: com.ibm.jbatch.container.exception.BatchContainerRuntimeException: Failure in Read-Process-Write Loop......Caused by: java.lang.NumberFormatException: For input string: "abc8800" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:492) at java.lang.Integer.parseInt(Integer.java:527) at com.oracle.javaee7.samples.batch.hello.SimpleItemReader.readItem(SimpleItemReader.java:100)
listaus 13
huomaa myös, että kun napsautat uudelleenkäynnistyspainiketta, luodaan uusi työn suoritus, mutta sen Työesitystunnus pysyy samana. Kun napsautat Päivitä-painiketta, PayrollJobSubmitter
servlet kutsuu restartBatchJob()
, joka näkyy listauksessa 14:
private long restartBatchJob(long lastExecutionId) throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); Properties props = new Properties(); props.setProperty("payrollInputDataFileName", payrollInputDataFileName); return jobOperator.restart(lastExecutionId, props);}
listauksessa 14
avainrivi listauksessa 14 On Call to JobOperator
’srestart()
method. Tämä menetelmä ottaa Properties
objektin aivan kuten start()
, mutta sen sijaan että se läpäisisi työn XML-tiedostonimen, se läpäisee Viimeksi epäonnistuneen työn suoritustunnuksen. Käyttämällä viimeksi epäonnistuneen työn suoritustunnusta eräajo voi hakea edellisen suorituksen viimeisen onnistuneen tarkistuspisteen. Haetut tarkastuspistetiedot siirretään open()
method of our SimpleItemReader
(ja ItemWriter
), jotta ne voivat jatkaa lukemista (ja kirjoittamista) viimeisestä onnistuneesta tarkastuspisteestä.
varmistaen, että selaimesi näyttää sivun Uudelleenkäynnistyspainikkeella, Muokkaa tiedostoa uudelleen ja poista ylimääräiset merkit kahdeksannesta tietueesta. Napsauta Käynnistä ja Päivitä-painiketta. Viimeisimmän suorituksen pitäisi näyttää valmis tila, kuten kuvassa 8 esitetään.
kuva 8
on aika katsoa lokitiedostoon ymmärtääkseen, mitä juuri tapahtui. Jälleen etsitään viestejä, joiden etuliitteenä on SimpleItemReader
, listaus 15 näyttää, mitä saatat nähdä:
Opened Payroll File. Will start reading from record number: 7]] checkpointInfo() called. Returning current recordNumber: 9]] checkpointInfo() called. Returning current recordNumber: 10]] close called.]]
listaus 15
kuten näette, meidän SimpleItemReader
’s open()
menetelmää kutsuttiin edellisen tarkistuspistearvon (joka oli ennätysluku 7) salliessa meidän SimpleItemReader
jättää kuusi ensimmäistä levyä väliin ja jatkaa lukemista seitsemänneltä levyltä.
erätöiden katselu GlassFish 4.0-hallintakonsolilla
voit katsoa listan kaikista erätöistä JobRepository
. Käynnistä selainikkuna ja siirry kohtaan localhost:4848
. Valitse sitten palvelin (Admin Server) vasemmassa paneelissa, kuten kuvassa 9.
kuva 9
voit klikata Batch-välilehteä, jossa luetellaan kaikki tälle GlassFish-palvelimelle lähetetyt erätyöt. Huomaa, että JobRepository
on toteutettu tietokantaa käyttäen ja siten työn yksityiskohdat selviävät GlassFish 4.0-palvelin käynnistyy uudelleen. Kuvassa 10 näkyvät kaikki JobRepository
.
kuva 10
Voit myös napsauttaa yhtä Suoritustunnusten alla luetelluista tunnuksista. Esimerkiksi 293: n klikkaaminen paljastaa yksityiskohtia juuri tästä suorituksesta:
kuva 11
tarkempia tietoja suorituksesta saa klikkaamalla päällä olevaa suoritusvaiheet-välilehteä.
kuva 12
Katso tämän sivun tilastot. Se osoittaa, kuinka monta lukua, kirjoitusta ja toimitusta suoritettiin tämän suorituksen aikana.
erätöiden katselu GlassFish 4.0 CLI: llä
voit myös tarkastella yksityiskohtia GlassFish 4: ssä käynnissä olevista töistä.0 palvelin käyttämällä komentoriviliitäntää (CLI).
nähdäksesi erätöiden luettelon, Avaa komentoikkuna ja suorita seuraava komento:
asadmin list-batch-jobs -l
sinun tulisi nähdä tuloste samanlaisena kuin kuvassa 13:
kuva 13
nähdäksesi luettelon eristä JobExecution
s, voit suorittaa tämän komennon:
asadmin list-batch-job-executions -l
sinun pitäisi nähdä tuloste samanlaisena kuin kuvassa 14:
kuva 14
komento listaa kunkin suorituksen valmiustilan ja myös kullekin suoritukselle siirretyt tehtäväparametrit.
lopuksi JobExecution
jokaisen vaiheen yksityiskohdista voisi käyttää seuraavaa komentoa:
asadmin list-batch-job-steps -l
kuva 15
huomioi stepmetrics-sarake. Se kertoo, kuinka monta kertaa ItemReader
ja ItemWriter
kutsuttiin ja kuinka monta toimitusta ja palautusta tehtiin. Nämä ovat erittäin arvokkaita mittareita.
CLI-tulosteen on vastattava hallintakonsolin näkymää, koska molemmat kyselevät samaa JobRepository
.
voit käyttää asadmin help <command-name>
saadaksesi lisätietoja CLI-komennoista.
johtopäätös
tässä artikkelissa nähtiin, miten kirjoitetaan, paketoidaan ja ajetaan yksinkertaisia eräsovelluksia, jotka käyttävät chunk-tyylisiä vaiheita. Näimme myös, miten eräajoajan tarkastuspiste-ominaisuus mahdollistaa epäonnistuneiden erätöiden helpon uudelleenkäynnistyksen. Silti JSR 352: n pintaa ei ole JUURI naarmutettu. Täydellinen joukko Java EE komponentteja ja ominaisuuksia käytettävissänne, kuten servlets, EJB pavut, CDI pavut, EJB automaattiset ajastimet, ja niin edelleen, monipuolinen erän sovelluksia voidaan kirjoittaa melko helposti.
tässä artikkelissa käsiteltiin (lyhyesti) myös GlassFish 4.0-hallintakonsolia ja Cli-tukea erän kyselyssä JobRepository
. Sekä hallintakonsoli että CLI tarjoavat arvokkaita tietoja työpaikoista ja vaiheista, joita voidaan käyttää mahdollisten pullonkaulojen havaitsemiseen.
JSR 352 tukee monia muita jännittäviä ominaisuuksia, kuten erät, splitit, virrat ja mukautetut tarkastuspisteet, joita käsitellään tulevissa artikkeleissa.
Katso myös
JSR 352
tekijästä
Mahesh Kannan on vanhempi ohjelmistoinsinööri Oraclen Cloud Application Foundation-tiimissä, ja hän on Java-erän JSR-asiantuntijaryhmän jäsen. Koska hänellä on laaja kokemus sovelluspalvelimista, säiliöistä ja hajautetuista järjestelmistä, hän on toiminut pääarkkitehtina ja ”konsulttina” monissa projekteissa, joissa rakennetaan innovatiivisia ratkaisuja Oraclen tuotteisiin.
Join the Conversation
Join the Java community conversation in Facebook, Twitter, and the Oracle Java Blog!