inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

4장. 작전3: FaultTolerant - 재시도로 구원하고, 스킵으로 처단하라 🏴‍☠️

FaultTolerant의 retryLimit() 횟수 질문

120

FWoody

작성한 질문수 4

1

킬구형 안녕, Fault Tolerant 쪽에서,

retryLimit()을 설명해줄 때

만약 retryLimit 값이 3일경우, "첫번째 호출시도 1번, 재시도 호출 2번"으로 총 3번이 호출된다고 했잖아.

재시도 횟수는 항상 retryLimit - 1 이라 그랬고.

 

근데 왜 "ItemProcessor의 예외 발생 시 재시도 - 아이템 단위로 재시도 관리"의 마지막 호출 결과 찍어준 부분에서,

 

retryLimit()은 3인데 왜 ItemProcessor는 4번이 호출되는거야?

위에 설명한대로라면 3번만 호출되어야 하는거 아냐?

java spring spring-boot spring-batch backend

답변 2

1

KILL-9

KILL-9@/bin/destroy:~$ man retry-limit

좋은 질문이군, FWoody! 섬세하고 예리한 관찰력이다. 

KILL-9@/bin/destroy:~$ grep -r "retryLimit=3" /system/batch

retryLimit이 3이라는 것은 "최대 3번까지 시도 허용"이라는 뜻이다. 실제 실행 시퀀스는 다음과 같다:

```bash
KILL-9@/bin/destroy:~$ ./itemprocessor --attempt=1  # FAILED
KILL-9@/bin/destroy:~$ ./itemprocessor --attempt=2  # FAILED  
KILL-9@/bin/destroy:~$ ./itemprocessor --attempt=3  # FAILED
KILL-9@/bin/destroy:~$ ./itemprocessor --attempt=4  # BLOCKED BY RETRY_POLICY -> 이게 실행결과에 시도 횟수 4가 기록된 이유이다
```

ItemProcessor는 실제로 3번만 호출된다. 4번째는 RetryTemplate(SimpleRetryPolicy)에 의해 **호출 자체가 차단**되어 즉시 스텝이 폭파된다.

KILL-9@error:~$ echo "RETRY LIMIT EXCEEDED - TERMINATING PROCESS"

로그에서 "4번 호출"처럼 보이는 건 Spring Batch Step(정확히는 바로 다음 작전에서 보게될 반복 컴포넌트) 4번째 시도를 **하려고 했지만** retry limit 방어막에 막혀서 실제 호출은 일어나지 않고 바로 죽어버린 것이다.

KILL-9@/bin/destroy:~$ sleep 666 && verify --brutal-mode

현재 외부 지역이라 예제 실행 결과를 직접 확인할 수 없다. 45분 내에 복귀해서 강의 내용 확인사살하겠다. 💀
(물론 안 봐도 내 분석이 맞지만 말이다... 훗💀)

 

██████╗  ██████╗ ██╗   ██╗██████╗ ██╗     ███████╗    ████████╗ █████╗ ██████╗ 
██╔══██╗██╔═══██╗██║   ██║██╔══██╗██║     ██╔════╝    ╚══██╔══╝██╔══██╗██╔══██╗
██║  ██║██║   ██║██║   ██║██████╔╝██║     █████╗         ██║   ███████║██████╔╝
██║  ██║██║   ██║██║   ██║██╔══██╗██║     ██╔══╝         ██║   ██╔══██║██╔═══╝ 
██████╔╝╚██████╔╝╚██████╔╝██████╔╝███████╗███████╗       ██║   ██║  ██║██║     
╚═════╝  ╚═════╝  ╚═════╝ ╚═════╝ ╚══════╝╚══════╝       ╚═╝   ╚═╝  ╚═╝╚═╝     
                                                           
                   [BANG! BANG!]
                      💀 💀 💀

확인 사살을 마쳤다. 앞선 나의 대답이 옳다.

retryLimit=3일 때 ItemProcessor는 정확히 3번만 호출된다. 4번째 시도는 RetryPolicy에 의해 호출 자체가 차단되어 즉시 스텝이 실패로 처리된다.

KILL-9@/bin/destroy:~$ grep -r "허용 가능한 총 시도 횟수" /lecture/content
>> 우리 강의 retryLimit() 설명에서 **'허용 가능한 총 시도 횟수'**라고 표현한 이유이다. 실제로는 그 횟수만큼만 시도가 허용되고, 그 이상은 시스템이 거부하기 때문이다.

KILL-9@danger:~# echo "추가 보충 예정"
너와 같이 착각하는 병사들이 분명 더 생길 수 있으니, 늦어도 일요일 안으로 예제 실행 결과 설명을 보충하겠다.

KILL-9@/bin/destroy:~$ crontab -e
0 0 * * SUN /bin/update-lecture-content --section=retry-limit

2

KILL-9

KILL-9@/bin/destroy:~$ cat << EOF

이래서 우리 강의가 다소 디테일하게 내결함성 기능을 파헤치는 이유다.(물론 과하지 않은 선에서 말이다)

KILL-9@error:~$ tail -f /var/log/production.log | grep "03:00"

예제 실행 결과를 분석하며 느꼈겠지만, 실무에서 예외가 터지고 저런 로그를 마주했다고 가정해보자.

```bash
[03:17:42] ERROR: ItemProcessor failed (attempt 1/3)
[03:17:43] RETRY: ItemProcessor failed (attempt 2/3)
[03:17:44] RETRY: ItemProcessor failed (attempt 3/3)
[03:17:45] RETRY: ItemProcessor called 4 times - but why?
[03:17:45] FATAL: Step execution failed
```

새벽 3시에 발생한 예외... 원인 파악도 하기 싫은데 Spring Batch 재시도 로그에서 "4번 호출"이라니? retryLimit=3인데 왜 4번?

KILL-9@danger:~# ps aux | grep "confused_developer"

그제서야 동작 파악하고 디버깅하는 것은 **개고생의 연속**이다.

KILL-9@/bin/destroy:~$ echo "사전 지식 없는 새벽 디버깅은 지옥이다" 

그래서 지금 이 고통스러운 디테일을 익혀두는 것이다. 
실전에서 멘붕하지 않도록 말이지. 💀

EOF​​​​​​​​​​​​​​​​

-1

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.

FWoody님, FaultTolerantretryLimit()과 관련된 질문을 주셨네요. retryLimit()은 설정된 값만큼의 호출을 포함하여, 최대 시도 회수를 지정하는 것입니다. 즉, retryLimit()으로 설정한 횟수만큼 ‘전체 호출’이 일어나게 됩니다.

예시 설명

  • retryLimit = 3: 첫 번째 정상 호출 + 재시도 2회
    • 여기서 첫 번째 호출은 초기 실행을 의미하기에, 이후 재시도가 두 번 더 발생하면 총 3회의 실행이 이루어집니다.

하지만, ItemProcessor나 다른 컴포넌트의 실제 호출 횟수는 다르게 보일 수 있습니다. 여기에서 중요한 점은 각 시도에서 새로운 예외가 발생할 경우, 비정상 종료 이후 재시도가 진행되는 과정에서의 호출이 추가로 발생할 수 있다는 것입니다.

즉, ItemProcessor에서 특정 조건으로 인해 예외가 발생하면 중간의 특정 프로세스가 다시 시도되는 과정에서의 추가 호출로 인해 결과적으로 4번 호출이 될 수 있습니다.

해당 사항에 대한 구체적인 프로세스는 로그나 추가 설정에 의해 달라질 수 있습니다. 따라서 실제 문제 해결 시, 사용 중인 설정과 로그를 바탕으로 구체적 확인을 추천드립니다.

이와 관련하여 더 알아보기 위해서는 다음 링크의 유사한 답변을 참고하실 수 있습니다:
- Fault Tolerant 및 retryLimit 관련 심층 분석

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

3

KILL-9

웃기지마라 ☠️

호출이 될 수도 있다라... 

양자컴퓨팅인가? 💀

형 이번에 낸 책이랑 강의 내용에 차이가 있어?

1

45

1

형 나 몰래 책내면 모를 줄 알고?

1

37

1

강의 중복 확인 요청

0

28

1

중복내용 제보?!

1

50

2

Json 요청 처리

1

52

2

[건의][6장][작전1] deprecated 메소드

1

55

2

[예제][3장][작전2] windows 에서 마지막 예제

0

43

1

[오타][3장][작전1] 형 이건 빨리 해줘

2

110

2

[오타] "리스너 활용: 시스템 완전 장악 매뉴얼" 부분

1

67

1

[오타] "JobScope와 StepScope 사용 시 주의사항" 부분

1

69

2

spring boot 4 + spring batch 6 설정 변경?

1

116

2

Batch 패키지 설계 — 실무에서 Job 단위 구조

1

102

1

Spring batch를 실행해줄 스케줄러와 batch 실행 환경

1

92

1

메타테이블에 데이터가 생기지 않는 이유

1

121

2

Spring Batch 4.3.10 ExecutionContext 한글 인코딩 이슈 관련 문의

1

118

2

@StepScope 또는 @JobScope와 JobOperator

1

154

5

Remote Partitioning

1

113

2

킬구형 실무에서는 JPA ItemReader / ItemWriter를 더 선호해? 아니면 JDBC itemReader/ItemWriter를 더 선호해?

1

145

2

병렬 중첩

1

105

3

형 코드에 public static class 이게 뭐야 ?

1

142

3

ExitStatus

1

71

2

Batch6: jobOperator.startNextInstance() throws UnexpectedJobExecutionException

1

130

5

jdbc 커서, 페이징에서 일대다 관계 데이터 뻥튀기 조회 처리 방법 질문

1

125

2

SkipPolicy는 여러번 불릴 수 있는가?

1

58

2