본문 바로가기
개발공부/JAVA Spring

API 재호출 라이브러리 - Spring Retry

by bzerome240 2023. 1. 22.

영화 비긴어게인

 

한번의 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
반응형

댓글