[Spring] Retry
Retry
서버를 운영하다보면 일시적인 오류가 종종 발생한다. 특히 큰 한덩어리로 관리되던 Monolithic Architecture 에서 Endpoint가 작은 단위로 분리되는 Micro Service Architecture(MSA) 로 바뀌면서 각 어플리케이션 간의 통신에서 이러한 일시적인 오류가 빈번하게 생기는 편이다.
이러한 네트워크 오류는 ‘재시도’를 함으로써 간단하고 강력하게 해결할 수 있다.
Spring에서는 재시도와 관련해서 @Retryable이라는 어노테이션, RetryRestTemplate, Circuit Breaker을 제공한다.
@Retryable
- Spring Application에 @EnableRetry 어노테이션을 추가한다.
- 재시도 하고 싶은 메소드에 @Retryable 어노테이션 추가한다.
- value: 설정한 특정 Exception이 발생했을 경우 retry
- maxAttempts : 최대 재시도 횟수 (기본 3회)
- backoff : 재시도 pause 시간
- 정해진 실패 회수를 초과할 경우 @Recover함수가 불리게 되는데, exception + 파라미터가 동일하다는 점에 주의해야 한다.
@Retryable(value = DataAccessResourceFailureException.class, maxAttempts = 2,
backoff = @Backoff(2000))
public void checkAndProcess(String userKey, String itemId) {
@Recover
public void recover(DataAccessResourceFailureException e, String userKey, String itemId) {
log.error("All retries have failed!, userKey:{} " + e.toString(), userKey);
}
RetryTemplate
- 여기저기 @Retryable을 붙여 사용하고 싶지 않다면 RetryTemplate을 이용해 서비스로 구현할 수 있다.
- 필요한 dependency를 추가하고, Bean 등록 후 생성한 Bean을 가지고 서비스를 구현하면 된다.
// dependency 추가
implementation 'org.springframework.retry:spring-retry'
@Bean
public RetryTemplate RetryTemplate() {
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1);//지정한 시간만큼 대기
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2); // 재시도 max count
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setBackOffPolicy(backOffPolicy);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}
@Service
public class SomeClass {
@Autowired
private RetryTemplate someRetryTemplate;
@Autowired
private Something something;
private String apply(SomeEntity someEntity) {
String result = someRetryTemplate.execute(context -> something.apply(someEntity));
return result;
}
}
Circuit Breaker
- MSA구조내에서 일상적으로 발생할 수 있는 에러로 대응하기 위해 나온 개념이다.
- 자동으로 모듈간의 호출 에러를 감지하고 연쇄로 장애가 나는것을 사전에 막을 수 있는 기능이다.
- Netflix에서는 이미 Hystrix라는 이름으로 개발이 되어 있다.
- spring-cloud-starter-netflix-hystrix 라이브러리 추가
- @EnableCircuitBreaker 어노테이션 추가
- 재시도할 부분에 @HystrixCommand 어노테이션을 추가
참고할만한 사이트
https://www.baeldung.com/spring-retry
https://github.com/Netflix/Hystrix
참고한 블로그
https://taetaetae.github.io/2020/03/29/better-rest-template-2-netflix-hystrix/