📚FOS Study
홈카테고리
홈카테고리
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
☕java/ spring-framework

FaultTolerant

약 3분
GitHub에서 보기

FaultTolerant

배치 작업에서 실패는 피할 수 없는 현실이다. 파일에 일부 잘못된 데이터가 저장되었을 수도 있고, 데이터베이스와의 토잇ㄴ이 일시적으로 실패할 수도이 있다. 그렇다고 해서 배치 작업이 중단되어도 괜찮을까?

Spring Batch의 잔인한 기본 오류 처리

스텝 실행 중 단 하나의 예외라도 발생하면?

ItemReader에서 읽는 중이든, ItemProcessor에서 처리 중이든, ItemWriter에서 쓰는 중이든 Spring Batch는 즉시 모든 실행을 중단하고 배치 잡 전체를 실패로 처리한다.

하지만 생각해보자.

  • 1,000만 개의 데이터를 처리하다 단 한 건의 오류로 작업을 실패시켜야 한다면?
  • 일시적인 네트워크 오류나 잘못된 형식의 데이터 하나 때문에 전체 배치를 다시 실행해야 한다면?

적절한 예외 처리 방법으로 재시도 가능한 예외는 재시도하고, 무시해도 되는 예외는 무시할 수 있어야 한다.
그러나 이게 구조적으로 쉽지만은 않다. 우리가 지금까지 살펴본 청크 지향 처리의 구조를 생각해보자.

청크 지향 처리의 구조적 한계

개발자는 ItemReader, ItemProcessor, ItemWriter 구현체를 스텝에 구성만할 뿐, 실제 실행은 Spring Batch의 Step이 담당한다. 즉, 아이템 처리 중 예외가 ㅂ라생해도 우리가 직접 개입할 기회가 없다.

다행이 이런 구조적 한계를 보완하기 위해 Spring Batch는 내결함성(FaultTolerance)기능을 제공한다.
이를 활용하면 간단한 구성만으로도 **재시도(Retry)**와 **건너뛰기(Skip)**로 청크 지향 처리에서 발생할 수 있는 다양한 예외 상황을 다룰 수 있다.

예를 들어,

  • 일시적 네트워크 오류로 인한 데이터베이스 쓰기 실패는 재시도로 해결할 수 있고,
  • 잘못된 형식의 데이터를 읽어 예외가 발생한 경우에는 건너뛰기로 깔끔하게 무시해버릴 수 있다.

참고 : 태크스릿 지향 처리는 내결함성(FaultTolerance)를 지원하지 않는다.
우리가 작성한 코드 내에서 try-catch를 사용해 발생 가능한 예외를 원하는 대로 처리할 수 있기 때문이다.

재시도(Retry)

말 그대로 실패한 작업을 다시 시도하는 것이다.
예를 들어 쓰기 중 데이터베이스 커넥션이 순간적으로 끊기거나 ItemProcessor의 외부 API 호출에서 일시적으로 타임아웃이 발생했을 떄, 잠시 후 다시 시도하면 정상적으로 처리될 가능성이 높다.

내결함성 기능의 핵심 무기 - RetryTemplate

내결함성 기능을 활성화하면 스텝은 RetryTemplate이라는 무기를 장착하게 된다.
RetryTemplate은 Spring Retry 프로젝트의 핵심 컴포넌트로, 쉽게 말해 작업이 실패하면 정해진 정책에 따라 다시 시도하는 컴포넌트다.

RetryTemplate의 메커니즘을 들여다보자. 다음 다이어 그램은 RetryTemplate.execute() 메서드가 내부적으로 어떻게 동작하는지를 단순화해서 보여준다.

RetryTemplate.execute()
        |
        v
    canRetry()?   <-- RetryPolicy 판단
       / \
      /   \
   YES     NO
    |       |
    v       v
retryCallback()   recoveryCallback()
 (재시도 수행)     (복구 로직 수행)
  • 재시도 가능 여부 판단 - canRetry()
    • 먼저 **canRetry()**를 통해 재시도 가능 여부를 판단한다.
    • 이 메서드는 사전에 정해진 재시도 정책(RetryPolicy)을 기반으로 "이 작업을 다시 시도해도 되는가?"를 결정한다.
  • 핵심 로직 실행 - retryCallback
    • 재시도가 가능하다고 판단되면 retryCallback을 호출한다.
    • 여기에는 우리가 실행하고자하는 핵심 비즈니스 로직이 담겨있다.
    • 중요한 점은 이 콜백이 재시도만을 위한 것이 아니라는 점이다.
    • 내결함성 기능이 활성화되면 최초 실행부터 재시도까지 모든 시도가 이 retryCallback을 통해 수행된다.
    • 즉, 정상적인 첫 실행도, 실패 후 재시도도 모두 RetryTemplate의 관할 하에 있다는 뜻이다.
  • 최후의 수단 - recoveryCallback
    • 만약 **canRetry()**가 "더 이상 재시도는 불가능하다"고 판단하면 어떻게 될까?
    • 이 떄 호출되는 것이 바로 recoveryCallback이다.
    • 최후의 수단으로, 기본적으로는 발생한 예외를 그대로 전파하거나 대체 로직을 수행한다.

이 메커니즘이 Spring Batch Step에 장착되면 어떤 일이 벌어질까?

  • 내결함성 모드가 활성화되면, ItemProcessor와 ItemWriter 호출 로직이 RetryTemplate의 retryCallback안으로 패키징된다.
  • 이 말인 즉, ItemProcessor와 ItemWriter 호출의 재시도뿐만 아니라 최초 실행 또한 이 RetryTemplate을 통해 수행된다는 뜻이다.

그렇다면 canRetry() 메서드에서는 재시도 가능 여부를 어떻게 판단할까?

재시도의 심판관 - RetryPolicy

java 카테고리의 다른 글 보기수정 제안하기
목차
  • FaultTolerant
  • Spring Batch의 잔인한 기본 오류 처리
  • 청크 지향 처리의 구조적 한계
  • 재시도(Retry)
  • 내결함성 기능의 핵심 무기 - RetryTemplate
  • 재시도의 심판관 - RetryPolicy