Yleiskatsaus Eräkäsittelyyn Java EE 7.0

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

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, yhden ItemProcessor ja yhden ItemWriter. Tässä kuviossa ItemReader 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 annetaan ItemWriter, 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.
  • 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ätietoja JobOperator, 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.xml 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) ItemReaderItemProcessor ja ItemWriterItemReaderItemProcessor 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”).

  1. Aloita kauppa.
  2. kutsuu ItemReader ja siirtää ItemReader lukemansa kohteen ItemProcessorItemProcessor käsittelee kohteen ja palauttaa käsitellyn kohteen eräajoon.
  3. eräajo toistaa vaiheen 2 item-count kertaa ja ylläpitää luetteloa käsitellyistä eristä.
  4. erän juoksuaika laskee ItemWriter, joka kirjoittaa item-count käsiteltyjen erien määrän.
  5. Jos poikkeuksia heitetään ItemReaderItemProcessor tai ItemWriter, tapahtuma epäonnistuu ja vaihe merkitään ”epäonnistui.”KS.JSR 352-eritelmän 5.2.1.2.1 kohta (poikkeusten ohittaminen).
  6. Jos poikkeuksia ei ole, erän suoritusaika saa tarkastuspistetiedot ItemReader ja ItemWriter (lisätietoja JSR 352-spesifikaation kohdassa 2.5). Erän suoritusaika toimittaa tapahtuman.
  7. 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 ItemReaderItemProcessor, 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 JobContextJobContext 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 prevCheckpointInfo 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ää kaikkiPayrollRecordesiintymät TIETOKANTATAULUKKOON yhteisen parlamentaarisen edustajakokouksen avulla. Luettelossa on korkeintaanitem-countmerkinnät (kimpaleen koko).

nyt kun meillä on JSL, ItemReaderItemProcessor, 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 ItemReaderItemProcessor 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, ItemReaderItemProcessorItemWriter, 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

kuva 2

klikkaa Laske palkanlaskenta-painiketta ja näet uuden merkinnän taulukossa, kuten kuvassa 3.

kuva 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

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

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 JobInstanceJobInstance 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 JobInstancediv>.

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 2item-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

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

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

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

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

kuva 10

Voit myös napsauttaa yhtä Suoritustunnusten alla luetelluista tunnuksista. Esimerkiksi 293: n klikkaaminen paljastaa yksityiskohtia juuri tästä suorituksesta:

Kuva 11

kuva 11

tarkempia tietoja suorituksesta saa klikkaamalla päällä olevaa suoritusvaiheet-välilehteä.

Kuva 12

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

kuva 13

nähdäksesi luettelon eristä JobExecutions, voit suorittaa tämän komennon:

asadmin list-batch-job-executions -l

sinun pitäisi nähdä tuloste samanlaisena kuin kuvassa 14:

Kuva 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

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!

Vastaa

Sähköpostiosoitettasi ei julkaista.