2025. 3. 16. 17:13ㆍSpring Microservice
🚀 [Spring Cloud + Resilience4j] Retry 패턴 완벽 가이드 (실패한 호출을 다시 시도하기)
지난 포스팅에서는 Resilience4j의 Circuit Breaker, Bulkhead, Fallback 패턴을 깊이 있게 다뤘습니다. 이번에는 네트워크 문제나 일시적인 장애 시 서비스 호출을 다시 시도하는 Retry(재시도) 패턴에 대해 명확히 알아보겠습니다.
🔄 Retry(재시도) 패턴이란?
Retry 패턴은 이름 그대로, 원격 서비스 호출에 실패했을 때 일정한 간격을 두고 여러 번 다시 시도하도록 설정하여 일시적인 장애(예: 네트워크 문제)를 극복하는 방식입니다.
Retry 패턴의 핵심은 다음과 같습니다.
- 💡 서비스 호출이 실패했을 때, 즉시 에러를 반환하지 않고 지정한 횟수만큼 재시도
- 💡 재시도 간격(waitDuration) 설정을 통해 무리한 호출 반복 방지
- 💡 특정 예외 유형만 재시도하도록 설정 가능
📌 Retry 패턴 설정 방법 (bootstrap.yml 설정 예시)
Resilience4j를 이용해 Retry 패턴을 설정하려면 다음과 같이 bootstrap.yml
파일에서 설정합니다.
📋 Retry 설정 예시 (bootstrap.yml)
resilience4j.retry:
instances:
retryLicenseService:
maxRetryAttempts: 5 # 최대 재시도 횟수 (디폴트값: 3)
waitDuration: 10000 # 각 재시도 사이의 대기 시간(ms) (디폴트값: 500ms)
retry-exceptions: # 재시도할 예외 목록 (디폴트값: 빈 목록)
- java.util.concurrent.TimeoutException
🔑 각 파라미터 의미와 디폴트값
파라미터 | 설명 | 디폴트값 |
---|---|---|
maxRetryAttempts |
재시도 최대 횟수 | 3 |
waitDuration |
재시도 간의 대기 시간 (밀리초) | 500ms |
retry-exceptions |
재시도할 예외 클래스 목록 (지정하지 않으면 모든 예외 재시도하지 않음) | Empty List |
이외에도 다음과 같은 추가적인 옵션도 사용할 수 있습니다.
- intervalFunction: 재시도 간격을 동적으로 조정하는 함수 설정
- retryOnResultPredicate: 응답 결과를 평가하여 재시도할지 여부를 결정하는 조건(predicate) 함수
- retryOnExceptionPredicate: 예외 유형을 평가하여 재시도할지 결정하는 조건(predicate) 함수
- ignoreExceptions: 특정 예외를 무시하여 재시도하지 않을 예외 목록
🛠️ 실제 서비스 메서드에서 Retry 패턴 적용하기
아래 코드는 Retry를 적용한 메서드의 완전한 예시입니다.
📋 서비스 메서드에 Retry 적용 예시 (LicenseService.java)
// 코드 일부 생략 (LicenseService.java)
@CircuitBreaker(name = "licenseService", fallbackMethod = "buildFallbackLicenseList")
@Retry(name = "retryLicenseService", fallbackMethod = "buildFallbackLicenseList")
@Bulkhead(name = "bulkheadLicenseService", fallbackMethod = "buildFallbackLicenseList")
public List<License> getLicensesByOrganization(String organizationId) throws TimeoutException {
logger.debug("getLicensesByOrganization Correlation id: {}",
UserContextHolder.getContext().getCorrelationId());
randomlyRunLong(); // 랜덤으로 장애를 유발하는 메서드
return licenseRepository.findByOrganizationId(organizationId);
}
🔍 어노테이션 상세 설명
@Retry(name = "retryLicenseService", fallbackMethod = "buildFallbackLicenseList")
- Retry 패턴 적용을 위한 설정이며, 서비스가 실패하면 지정된 횟수만큼 다시 시도
- 최종적으로 실패하면
fallbackMethod
에서 지정한 폴백 메서드를 호출하여 대체 응답을 반환
@CircuitBreaker
,@Bulkhead
와 함께 결합하여 복합적인 장애 대응 가능
🎯 Retry 패턴의 동작 원리 요약
Retry 패턴이 동작하는 방식은 다음과 같습니다.
- 서비스 호출 시도 (최초 호출)
- 호출이 예외(TimeoutException 등)로 실패하면
- 설정된 간격(waitDuration)을 기다림
- 지정한 최대 횟수(maxRetryAttempts)까지 2~3번 과정 반복
- 모든 재시도가 실패하면 최종적으로 폴백 메서드 실행 (fallback)
🔖 Retry 패턴 활용 시 주의사항!
Retry는 강력한 패턴이지만 무작정 사용하면 더 큰 장애를 유발할 수도 있습니다. 아래의 내용을 꼭 기억하세요!
- 🔥 Retry 간격(
waitDuration
)이 너무 짧으면 장애 상황에서 서비스 과부하를 유발할 수 있습니다. - 🔥 과도한 재시도 횟수(
maxRetryAttempts
) 설정은 요청 큐가 밀리는 원인이 될 수 있습니다. - 🔥 Retry 후에도 실패하면, 사용자에게 의미 있는 fallback 응답을 제공하는 것이 중요합니다.
🚨 다양한 패턴의 조합 활용 (Resilience4j의 강력한 특징)
Resilience4j는 Retry, Circuit Breaker, Bulkhead, Rate Limiter, Fallback 등 여러 패턴을 동시에 조합하여 사용할 수 있습니다. 위 코드 예제에서도 Retry와 Circuit Breaker, Bulkhead를 한 번에 사용하는 사례를 확인할 수 있습니다.
실제 운영 환경에서는 이러한 여러 패턴 조합을 통해 더욱 안정적인 마이크로서비스 환경을 구축할 수 있습니다. ✨
🔗 관련 문서 및 참고 링크
Retry 패턴에 대한 더 자세한 옵션과 사용법을 확인하려면 Resilience4j 공식 문서를 참조하세요.
🔥 마무리
이번 포스팅에서는 Resilience4j의 Retry 패턴에 대한 상세한 개념과 설정 방법을 빠짐없이 완벽하게 살펴봤습니다.
Retry 패턴을 적절하게 사용하면 일시적인 장애 상황에서도 사용자에게 더 안정적이고 신뢰할 수 있는 서비스를 제공할 수 있습니다. 🚀✨
다음 글에서는 Rate Limiter를 알아보겠습니다. 감사합니다! 🙌😊
'Spring Microservice' 카테고리의 다른 글
ThreadLocal and Resilience4j (1) | 2025.03.16 |
---|---|
Implementing the rate limiter pattern (0) | 2025.03.16 |
99 퍼센타일(percentile) (0) | 2025.03.16 |
Implementing the bulkhead pattern (1) | 2025.03.16 |
Fallback processing (0) | 2025.03.16 |