태그
#SPRINGBOOT
#ASYNC
#ERROR
#RETRYABLE
Spring @Async 실패 시 자동 재실행(재시도) 방법 정리
2025년 6월 17일 19:58

Spring에서 비동기 작업을 처리할 때 @Async 어노테이션을 자주 사용합니다. 하지만 비동기 메서드에서 예외가 발생했을 때, 이를 자동으로 재실행(재시도)하고 싶다면 어떻게 해야 할까요? 이번 글에서는 Spring Retry 라이브러리를 활용해 @Async 메서드의 실패 시 자동 재실행 방법을 정리합니다.
1. @Async에서 예외 처리의 한계
@Async가 붙은 메서드는 별도의 스레드에서 실행되기 때문에, 예외가 발생해도 호출자에게 바로 전달되지 않습니다.
따라서 단순히 try-catch로는 예외 상황을 감지하거나, 자동으로 재실행하는 것이 어렵습니다.
2. Spring Retry와 @Retryable의 활용
이럴 때 사용할 수 있는 것이 바로 Spring Retry 라이브러리입니다.
@Retryable 어노테이션을 사용하면 지정한 예외가 발생했을 때 자동으로 재시도할 수 있습니다.
적용 방법
- 설정 파일에
@EnableAsync와@EnableRetry를 추가합니다. - 비동기 메서드에
@Async와@Retryable을 함께 붙입니다. @Retryable의 속성(maxAttempts, backoff 등)으로 재시도 횟수와 간격을 설정할 수 있습니다.- 모든 재시도에도 실패하면
@Recover메서드가 호출되어 후처리를 할 수 있습니다.
3. 예시 코드
@EnableAsync
@EnableRetry
@Configuration
public class AppConfig {}
@Async
@Retryable(
value = {RuntimeException.class}, // 재시도할 예외 타입
maxAttempts = 4, // 최대 4번 시도
backoff = @Backoff(delay = 2000) // 2초 간격
)
public void asyncMethod(String param) {
// 실패 가능성이 있는 로직
throw new RuntimeException("실패!");
}
@Recover
public void recover(RuntimeException e, String param) {
// 모든 재시도 실패 시 실행되는 복구 로직
}
4. 유의사항
@Async와@Retryable은 반드시 public 메서드에만 적용해야 하며, 같은 클래스 내에서 자기 자신을 호출하면 프록시가 적용되지 않아 동작하지 않습니다.- 반환 타입이 Future, CompletableFuture 등일 경우 호출부에서 예외를 직접 확인할 수도 있습니다.
- Spring Retry를 사용하지 않고 직접 재시도 로직을 구현하려면, 실패 이벤트를 기록하고 스케줄러로 재실행하는 방법도 있습니다.
5. 마무리
Spring에서는 @Async와 @Retryable을 함께 사용함으로써, 비동기 작업의 실패 시 자동 재실행을 손쉽게 구현할 수 있습니다.
여기에 @Recover 메서드를 활용하면, 모든 재시도 실패 시에도 안정적으로 후처리를 할 수 있습니다.
비동기 작업의 신뢰성과 안정성을 높이고 싶을 때 위 방법을 적극적으로 활용해보세요!