λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Spring/Spring Batch

Spring Batch (12) Retry

by 주발2 2023. 3. 4.
λ°˜μ‘ν˜•

πŸ”—  Spring Batch Retry (Tasklet 기반)

예제 μ½”λ“œλŠ” κΉƒν—ˆλΈŒμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€ :)

μ„œλΉ„μŠ€μ—μ„œ μž¬μ‹œλ„κ°€ ν•„μš”ν•œ κ²½μš°λŠ” μ–Έμ œμΌκΉŒμš”? λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 였λ₯˜μ™€ 같은 λ‚΄κ°€ μž‘μ„±ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μ˜ν•΄ λ°œμƒν•œ μ—λŸ¬λŠ” μž¬μ‹œλ„λ₯Ό ν•˜λ”λΌλ„ λ™μΌν•˜κ²Œ μ‹€νŒ¨ν•  κ²½μš°κ°€ ν½λ‹ˆλ‹€.

 

ν•˜μ§€λ§Œ λ„€νŠΈμ›Œν¬μ™€ 같은 μΌμ‹œμ μœΌλ‘œ λ°œμƒν•  수 μžˆλŠ” μž₯μ•  μƒν™©μ—μ„œλŠ” μœ μš©ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 

λŒ€ν‘œμ μœΌλ‘œλŠ” λ°μ΄ν„°λ² μ΄μŠ€ I/Oμ™€μ˜ νƒ€μž„μ•„μ›ƒ, API 호좜 μ‹œ λ°œμƒν•˜λŠ” νƒ€μž„μ•„μ›ƒ 등이 μžˆκ² λ„€μš”.

 

졜근 μ‚¬λ‚΄μ—μ„œ μ™ΈλΆ€ APIλ₯Ό ν˜ΈμΆœν•˜λŠ” κ³Όμ •μ—μ„œ κ°„ν—μ μœΌλ‘œ μ•„λž˜μ™€ 같은 μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

reactor.core.Exceptions$ReactiveException: io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: 연결이 μƒλŒ€νŽΈμ— μ˜ν•΄ λŠμ–΄μ§

μ΅œκ·Όμ— κ°‘μžκΈ° λ°œμƒν•œ μΌ€μ΄μŠ€λ‘œ 아직 μ •ν™•ν•œ 원인은 νŒŒμ•…ν•˜μ§€ λͺ»ν–ˆμ§€λ§Œ, ν•΄λ‹Ή APIλ₯Ό μž¬μ²˜λ¦¬ν•˜λ©΄ 2~3회 μ‹œλ„ ν›„ 정상 μ²˜λ¦¬κ°€ λ©λ‹ˆλ‹€.

ν•΄λ‹Ή APIλ₯Ό ν˜ΈμΆœν•˜λŠ” ν”„λ‘œμ νŠΈλŠ” Spring Batch ν”„λ‘œμ νŠΈλ‘œ Chunk Orientedκ°€ μ•„λ‹Œ Tasklet 기반으둜 Job이 μ΄λ£¨μ–΄μ ΈμžˆμŠ΅λ‹ˆλ‹€.

 

λ”°λΌμ„œ Tasklet 기반 Batchμ—μ„œλŠ” Retry κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” 방법에 λŒ€ν•΄ κ°„λž΅νžˆ μ‚΄νŽ΄λ΄…λ‹ˆλ‹€.

 

 

 

RetryOperations, RetryTemplate

Retry κΈ°λŠ₯은 Spring Batch 2.2 버전뢀터 μ œμ™Έλ˜μ–΄μ„œ ν˜„μž¬λŠ” Spring retry λΌμ΄λΈŒλŸ¬λ¦¬μ— μ‘΄μž¬ν•˜λŠ”λ°μš”, μ΄λŠ” retry κΈ°λŠ₯이 μŠ€ν”„λ§μ˜ λ‹€λ₯Έ ν”„λ ˆμž„μ›Œν¬μ—λ„ μœ μš©ν•œ κΈ°λŠ₯이기 λ•Œλ¬Έμ— Batchκ°€ μ•„λ‹Œ spring λΌμ΄λΈŒλŸ¬λ¦¬μ— ν¬ν•¨λ˜μ—ˆλ‹€κ³  ν•©λ‹ˆλ‹€.

The ability to retry an operation via the RetryTemplate has always been a feature of Spring Batch. That ability has been identified as a useful feature for other frameworks (Spring Integration for example). With the 2.2.0 release, the retry logic has been extracted from Spring Batch into it's own library called Spring Retry. With this change, there are two main impacts. The first is that the majority of the 
org.springframework.batch.retry package has been moved into this new library. With that move, the package name has also dropped the batch to become org.springframework.retry

https://docs.spring.io/spring-batch/docs/2.2.x/reference/html/whatsNew.html

Spring RetryλŠ” μ΅œμƒμœ„ RetryOperations μΈν„°νŽ˜μ΄μŠ€κ°€ μ‘΄μž¬ν•˜κ³ , κ΅¬ν˜„μ²΄μΈ RetryTemplate ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

RetryTemplate ν΄λž˜μŠ€μ—μ„œ μž¬μ‹œλ„ μ΅œλŒ€ 횟수, μž¬μ‹œλ„ 간격, Listeners, μž¬μ‹œλ„ μ²˜λ¦¬ν•  μ˜ˆμ™Έ μ„€μ • 등을 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

 

RetryConfig

RetryTemplate을 Bean으둜 λ“±λ‘ν•˜μ—¬ μž¬μ‹œλ„ ν•  횟수, 간격, μ˜ˆμ™Έ 클래슀 등을 μ„€μ •ν•©λ‹ˆλ‹€.

custom λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ“ , 직접 값을 μ„€μ •ν•˜λŠ” maxAttempts와 같은 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ“  크게 상관은 μ—†μŠ΅λ‹ˆλ‹€.

(μž¬μ‹œλ„ κΈ°λ³Έ 횟수: 3, μž¬μ‹œλ„ κΈ°λ³Έ 간격: 1초)

 

retryOn() 및 notRetryOn() λ©”μ„œλ“œλŠ” ν•˜λ‚˜λ§Œ μ‚¬μš©μ„ ν•˜λΌκ³  ν•©λ‹ˆλ‹€.

(retryOn() λ©”μ„œλ“œμ™€ notRetryOn() λ©”μ„œλ“œμ— λ™μΌν•œ μ˜ˆμ™Έλ₯Ό μ„€μ •ν•˜λŠ” 경우 등을 κ³ λ €ν•˜μ—¬ ν•˜λ‚˜μ˜ λ©”μ„œλ“œλ§Œ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 것이 아닐지 μ‘°μ‹¬μŠ€λ ˆ 생각해 λ΄…λ‹ˆλ‹€.. 🧐)

 

 

 

Spring Batch Job

Jobμ—μ„œ RetryTemplate을 μ£Όμž…λ°›κ³ , μ‹€μ œ λ‘œμ§μ„ μ²˜λ¦¬ν•˜λŠ” Taskletμ—μ„œ execute() λ©”μ„œλ“œλ₯Ό 톡해 μž¬μ‹œλ„ κΈ°λŠ₯을 κ΅¬ν˜„ν•©λ‹ˆλ‹€.

 

RetryTemplateμ—λŠ” μ—¬λŸ¬ 개의 execute() λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

μ €λŠ” 두 번째 RetryCallback, RecoveryCallbackλ₯Ό 인자둜 λ°›λŠ” λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν–ˆκ³ , μœ„ λ©”μ„œλ“œλ“€μ€ λͺ¨λ‘ doExecute() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœμ„ ν•˜λŠ”λ°μš”, 이 λ©”μ„œλ“œκ°€ μ‹€μ œλ‘œ μž¬μ²˜λ¦¬κ°€ μ΄λ£¨μ–΄μ§€λŠ” κ³³μž…λ‹ˆλ‹€.

 

RetryTemplate - execute()

μ‹€μ œ retry 둜직이 μ‹€ν–‰λ˜λŠ” RetryTemplate의 doExecute() λ©”μ„œλ“œμΈλ°μš”, λ™μž‘ 과정은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

(λ©”μ„œλ“œκ°€ κΈΈμ–΄μ„œ 핡심 λ‘œμ§μ„ μ œμ™Έν•œ μ½”λ“œλŠ” 일뢀 μ œκ±°ν•˜μ˜€μŠ΅λ‹ˆλ‹€.)

  1. μž¬μ‹œλ„κ°€ κ°€λŠ₯ν•œ λ™μ•ˆ 반볡적 μ‹€ν–‰
  2. μž¬μ‹œλ„ 처리
  3. 2)μ—μ„œ μž¬μ‹œλ„ 처리 ν›„ μ˜ˆμ™Έκ°€ λ°œμƒν•œ 경우, lastException μ„€μ • 및 μž¬μ‹œλ„ 횟수(count) + 1 증가 
  4. backOffλ₯Ό μœ„ν•΄ μž¬μ‹œλ„κ°€ κ°€λŠ₯ν•œμ§€ λ‹€μ‹œ 확인
  5. μž¬μ‹œλ„ 간격 backOff
  6. μž¬μ‹œλ„ μ΅œλŒ€ 횟수 μ‹œλ„ ν›„ μ‹€νŒ¨μΈ 경우 Recover 둜직 μˆ˜ν–‰

 

 

Spring Batch Job Test

Job을 μ‹€ν–‰ν•΄ 보면 1초 κ°„κ²©μœΌλ‘œ μž¬μ‹œλ„κ°€ 되고, maxAttempt인 3회 μ‹œλ„ ν›„ μ‹€νŒ¨ν•  경우 Recover 둜직이 μˆ˜ν–‰μ΄ λ©λ‹ˆλ‹€.

 

 

 

@Retryable 및 Chunk Oriented Retry

Retryλ₯Ό κ΅¬ν˜„ν•˜λŠ” λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μ–΄λ…Έν…Œμ΄μ…˜κ³Ό Chunk 기반 μ μš©ν•˜λŠ” 방법이 μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

1. @Retryable

@Retryable은 μ™ΈλΆ€ 라이브러리 μΆ”κ°€ 및 @Retryable μ–΄λ…Έν…Œμ΄μ…˜κ³Ό μ„€μ • νŒŒμΌμ— @EnableRetry만 μ„ μ–Έν•˜λ©΄ λμž…λ‹ˆλ‹€.

(μ°Έκ³ : https://www.baeldung.com/spring-retry)

 

2. Chunk Oriented Retry

Chunk 기반 Batchμ—μ„œλ„ RetryλŠ” 맀우 κ°„λ‹¨ν•˜κ²Œ 적용이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

(μ°Έκ³ : https://www.baeldung.com/spring-batch-retry-logic)

 

λ°˜μ‘ν˜•

'Spring > Spring Batch' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

Spring Batch (11) Repeat  (0) 2023.01.15
Spring Batch (10) @JobScope, @StepScope  (0) 2022.12.08
Spring Batch (9) JobParametersValidator  (0) 2022.11.13
Spring Batch (8) JobLauncher  (0) 2022.11.11
Spring Batch (7) JobRepository  (0) 2022.11.08

λŒ“κΈ€