Konfigurerer Logg på nytt i Spring Batch

1. Oversikt

Som standard mislykkes en Spring-batchjobb for feil oppstått under utførelsen. Men til tider kan det være lurt å forbedre applikasjonens elastisitet for å håndtere periodiske feil.

I denne raske opplæringen, Vi vil utforske hvordan du konfigurerer logg på nytt i Spring Batch-rammeverket.

2. Et eksempel på en brukssak

La oss si at vi har en batchjobb som leser en inndata CSV-fil:

brukernavn, brukerid, transaksjonsdato, transaksjonsbeløp sammy, 1234, 31/10/2015, 10000 john, 9999, 3/12/2015, 12321

Deretter behandler den hver post ved å trykke på et REST-sluttpunkt for å hente brukerens alder og postnummer attributter:

offentlig klasse RetryItemProcessor implementerer ItemProcessor {@Override offentlig transaksjonsprosess (Transaksjonstransaksjon) kaster IOException {log.info ("RetryItemProcessor, prøver å behandle: {}", transaksjon); HttpResponse respons = fetchMoreUserDetails (transaction.getUserId ()); // parse brukerens alder og postkode fra svar og oppdater transaksjon ... returtransaksjon; } ...}

Og til slutt genererer det en konsolidert produksjon XML:

  10000.0 2015-10-31 00:00:00 1234 sammy 10 430222 ... 

3. Legge til forsøk på ItemProsessor

Nå, hva om forbindelsen til REST-endepunktet går ut på tider på grunn av nettverkssikkerhet? I så fall mislykkes batchjobben vår.

I slike tilfeller foretrekker vi at den mislykkede varebehandlingen blir prøvd på nytt et par ganger. Og så, la oss konfigurere batch-jobben vår til å utføre opptil tre forsøk i tilfelle feil:

@Bean public Step retryStep (ItemProcessor processor, ItemWriter writer) kaster ParseException {return stepBuilderFactory .get ("retryStep") .chunk (10) .reader (itemReader (inputCsv)). Prosessor (prosessor) .writer (skribent) .faultTolerant ( ) .retryLimit (3) .retry (ConnectTimeoutException.class) .retry (DeadlockLoserDataAccessException.class) .build (); }

Her har vi en oppfordring til feiltolerant() for å aktivere funksjonaliteten på nytt. I tillegg vi bruker prøv på nytt og prøv på nytt for å definere unntakene som kvalifiserer for et nytt forsøk og det maksimale antallet nye prøver for en vare, henholdsvis.

4. Testing av forsøkene

La oss ha et testscenario der REST-endepunktet kommer tilbake alder og postnummer var nede bare en stund. I dette testscenariet får vi en ConnectTimeoutException bare for de to første API-samtalene, og den tredje samtalen vil lykkes:

@Test offentlig ugyldig nårEndpointFailsTwicePasses3rdTime_thenSuccess () kaster Unntak {FileSystemResource expectResult = ny FileSystemResource (EXPECTED_OUTPUT); FileSystemResource actualResult = ny FileSystemResource (TEST_OUTPUT); når (httpResponse.getEntity ()) .thenReturn (ny StringEntity ("{\" age \ ": 10, \" postCode \ ": \" 430222 \ "}")); // mislykkes for de to første samtalene og går tredje gang når (httpClient.execute (any ())) .thenThrow (new ConnectTimeoutException ("Timeout count 1")) .thenThrow (new ConnectTimeoutException ("Timeout count 2")). thenReturn (httpResponse); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), er ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), er ("KOMPLETT")); AssertFile.assertFileEquals (forventet resultat, faktisk resultat); }

Her ble jobben fullført. I tillegg er det tydelig fra loggene den første plata med id = 1234 mislyktes to ganger og lyktes til slutt på tredje prøve:

19: 06: 57.742 [main] INFO osbatch.core.job.SimpleStepHandler - Utføringstrinn: [retryStep] 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - Forsøk på å behandle bruker med id = 1234 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - Forsøk på å behandle bruker med id = 1234 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - Forsøk på å behandle bruker med id = 1234 19:06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - Forsøk på å behandle bruker med id = 9999 19: 06: 57.773 [main] INFO osbatch.core.step.AbstractStep - Trinn: [retryStep] utført i 31ms

På samme måte, la oss ha det en annen prøvesak for å se hva som skjer når alle prøvene er oppbrukt:

@Test offentlig ugyldig når EndpointAlwaysFail_thenJobFails () kaster unntak {når (httpClient.execute (any ())) .thenThrow (nye ConnectTimeoutException ("Endpoint er nede")); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), er ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), er ("FAILED")); assertThat (actualJobExitStatus.getExitDescription (), inneholderString ("org.apache.http.conn.ConnectTimeoutException")); }

I dette tilfellet, tre forsøk ble forsøkt for den første posten før jobben endelig mislyktes på grunn av a ConnectTimeoutException.

5. Konfigurere forsøk ved hjelp av XML

Til slutt, la oss se på XML-ekvivalenten til konfigurasjonene ovenfor:

6. Konklusjon

I denne artikkelen lærte vi hvordan vi konfigurerer forsøkslogikk i Spring Batch. Vi så på både Java- og XML-konfigurasjoner.

Vi brukte også en enhetstest for å se hvordan forsøkene fungerte i praksis.

Som alltid er eksempelkoden for denne opplæringen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found