한번의 API 호출실패로 비지니스 로직을 모두 실패처리하는 것은 몇번 다시 호출하는 것보다 리소스 낭비가 클 수 있다.
따라서 보통 최대 3번의 재호출을 하는 방법을 사용한다.
단, Read Timeout 상황은 특정 시간동안 네트워크 이슈가 지속되는 경우가 많기 때문에 재시도를 하더라도 모두 실패할 수 있다.
재호출 고려해야할점
- 재시도를 몇 번 실핼할 것인가?
- 재시도 하기 전 지연시간을 얼마나 줄 것인가?
- 재시도를 모두 실패했을 경우 어떻게 처리할 것인가?
-> 순수 코드로 구현할 수 있지만, 비지니스 로직에 집중하고 유지보수가 쉽도록 스프링 라이브러리를 사용하자!
Spring Retry 라이브러리
구현 방법 1) 어노테이션 2) RetryTemplate
@EnableRetry : Spring Retry 활성화
@Retryable : 메소드에 재시도 기능 추가. Exeption이 발생하면 재시도
- default 재시도 최대 3번, 딜레이 1초
// RuntimeExeption이 발생하면 최대 2번, 3초 딜레이 조건으로 재시도한다.
@Retryable(
value = {RuntimeException.class},
maxAttempts = 2,
backoff = @Backoff(delay = 3000)
)
@Recover : 모두 실패한경우 FallBack 처리
* return 타입을 꼭 맞춰준다.
@Recover
public KakaoApiResponseDto recover(RuntimeException e, String address) {
log.error("All the retries failed address:{} error:{}", address, e.getMessage());
return null;
}
요청하는 쪽에서 실패 응답을 받아야하는데, 외부 API인경우 컨트롤하기가 까다롭다.
=> MockWebServer 사용
의존성 추가
// spring retry
implementation 'org.springframework.retry:spring-retry'
// mockWebServer
testImplementation('com.squareup.okhttp3:okhttp:4.10.0')
testImplementation('com.squareup.okhttp3:mockwebserver:4.10.0')
Spring Retry 테스트 코드
def "requestAddressSearch retry fail"() {
given:
def uri = mockWebServer.url("/").uri()
when:
mockWebServer.enqueue(new MockResponse().setResponseCode(429))
mockWebServer.enqueue(new MockResponse().setResponseCode(429))
def result = kakaoAddressSearchService.requestAddressSearch(inputAddress)
then:
2 * kakaoUriBuilderService.buildUriByAddressSearch(inputAddress) >> uri
result == null
}
728x90
반응형
'개발공부 > JAVA Spring' 카테고리의 다른 글
Java 거리 계산 알고리즘 - Haversine formula (0) | 2023.01.24 |
---|---|
Java/Spring 공공 기관 데이터 셋업 하기 (0) | 2023.01.24 |
Spring @Transactional 이란? (0) | 2023.01.22 |
JPA Auditing (0) | 2023.01.21 |
troubleshooting - Failed to load ApplicationContext (0) | 2023.01.19 |
댓글