Konfiguriranje logike ponovnog pokušaja u Spring Batchu

1. Pregled

Prema zadanim postavkama, proljetni batch posao ne uspije za bilo kakve pogreške nastale tijekom njegovog izvođenja. Međutim, ponekad bismo mogli poboljšati otpornost naše aplikacije na rješavanje povremenih kvarova.

U ovom brzom vodiču, istražit ćemo kako konfigurirati logiku ponovnog pokušaja u okviru Spring Batch.

2. Primjer upotrebe

Recimo da imamo batch posao koji čita ulaznu CSV datoteku:

korisničko ime, korisničko ime, datum_ transakcije, iznos_transakcije sammy, 1234, 31.10.2015., 10000 John, 9999, 12.3.2015., 12321

Zatim obrađuje svaki zapis tako što pogodi REST krajnju točku kako bi dohvatio korisnikov dob i poštanski broj atributi:

javna klasa RetryItemProcessor implementira ItemProcessor {@Override javni proces transakcije (transakcijska transakcija) baca IOException {log.info ("RetryItemProcessor, pokušaj obrade: {}", transakcija); HttpResponse odgovor = fetchMoreUserDetails (action.getUserId ()); // raščlanjujemo dob i postCode korisnika iz odgovora i ažuriramo transakciju ... povrat transakcije; } ...}

I na kraju, generira konsolidirani izlaz XML:

  10000,0 2015-10-31 00:00:00 1234 sammy 10 430222 ... 

3. Dodavanje ponovnih pokušaja u PredmetProcesor

Sad, što ako se veza s REST krajnjom točkom istekne zbog neke mrežne sporosti? Ako je tako, naš batch posao neće uspjeti.

U takvim bismo slučajevima radije pokušali nekoliko puta pokušati s neuspjelom obradom predmeta. I tako, konfigurirajmo svoj batch posao da izvrši do tri ponovljena pokušaja u slučaju neuspjeha:

@Bean public Step retryStep (ProcessProcessor Processor, Writer ItemWriter) baca ParseException {return stepBuilderFactory .get ("retryStep") .chunk (10) .reader (itemReader (inputCsv)) .processor (processor) .writer (writer) .faultTolerant ) .retryLimit (3) .retry (ConnectTimeoutException.class) .retry (DeadlockLoserDataAccessException.class) .build (); }

Evo, imamo poziv za faultTolerant () za omogućavanje funkcije ponovnog pokušaja. Dodatno, koristimo pokušati ponovo i pokušati ponovno ograničiti za definiranje iznimaka koji ispunjavaju uvjete za ponovni pokušaj i maksimalnog broja ponovljenih pokušaja za stavku.

4. Testiranje ponovljenih pokušaja

Imajmo testni scenarij u kojem se vraća REST krajnja točka dob i poštanski broj je pao samo neko vrijeme. U ovom testnom scenariju dobit ćemo ConnectTimeoutException samo za prva dva API poziva, a treći poziv će uspjeti:

@Test public void whenEndpointFailsTwicePasses3rdTime_thenSuccess () baca izuzetak {FileSystemResource očekujeResult = novi FileSystemResource (EXPECTED_OUTPUT); FileSystemResource actualResult = novi FileSystemResource (TEST_OUTPUT); when (httpResponse.getEntity ()). thenReturn (new StringEntity ("{\" age \ ": 10, \" postCode \ ": \" 430222 \ "}")); // ne uspijeva za prva dva poziva i prolazi treći put nadalje kada (httpClient.execute (bilo koji ())). thenThrow (novi ConnectTimeoutException ("Timeout count 1")). thenThrow (novi ConnectTimeoutException ("Timeout count 2")). thenReturn (httpResponse); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), je ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), je ("ZAVRŠENO")); AssertFile.assertFileEquals (očekivani rezultat, stvarni rezultat); }

Ovdje je naš posao uspješno završen. Osim toga, iz evidencija je vidljivo da prvi zapis sa id = 1234 dva puta nije uspio i napokon je uspio u trećem ponovnom pokušaju:

19: 06: 57.742 [glavna] INFO osbatch.core.job.SimpleStepHandler - Izvršni korak: [retryStep] 19: 06: 57.758 [glavna] INFO obbatch.service.RetryItemProcessor - Pokušaj obrade korisnika s id = 1234 19: 06: 57.758 [glavna] INFO obbatch.service.RetryItemProcessor - Pokušaj obrade korisnika s id = 1234 19: 06: 57.758 [glavna] INFO obbatch.service.RetryItemProcessor - Pokušaj obrade korisnika s id = 1234 19:06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - Pokušaj obrade korisnika s id = 9999 19: 06: 57.773 [main] INFO osbatch.core.step.AbstractStep - Korak: [retryStep] izvršen za 31 ms

Slično tome, imajmo još jedan testni slučaj da se vidi što se događa kada se iscrpe svi pokušaji:

@Test public void whenEndpointAlwaysFail_thenJobFails () baca iznimku {when (httpClient.execute (any ())). ThenThrow (new ConnectTimeoutException ("Endpoint is down")); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), je ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), je ("FAILED")); assertThat (actualJobExitStatus.getExitDescription (), containsString ("org.apache.http.conn.ConnectTimeoutException")); }

U ovom slučaju, tri pokušaja pokušana su za prvi zapis prije nego što je posao napokon propao zbog a ConnectTimeoutException.

5. Konfiguriranje ponovnih pokušaja pomoću XML-a

Na kraju, pogledajmo XML ekvivalent gore navedenim konfiguracijama:

6. Zaključak

U ovom smo članku naučili kako konfigurirati logiku ponovnog pokušaja u Spring Batchu. Pogledali smo i Java i XML konfiguracije.

Također smo koristili jedinstveni test kako bismo vidjeli kako su ponovljeni pokušaji funkcionirali u praksi.

Kao i uvijek, primjer koda za ovu lekciju dostupan je na GitHubu.


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