Kotlin Spring + Mybatis + Mysql 샘플 데이터 토이프로젝트 -7 Resilience4J Retry 적용

선종우·2024년 8월 22일
0

Spring 노트

목록 보기
7/10
  • 외부 API 사용 시 장애대응을 위한 재시도 기능을 구현하였다.
    Resilience4j 예제 깃헙
  • gradle에 의존성 설정을 해준다.
dependencies {
	implementation("org.springframework.boot:spring-boot-starter-actuator")
	implementation("org.springframework.boot:spring-boot-starter-aop")
	implementation("io.github.resilience4j:resilience4j-spring-boot3")
	implementation("io.github.resilience4j:resilience4j-all") // Optional, only required when you want to use the Decorators class
}
  • resilience4j 관련 설정을 해준다.
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3              #The maximum number of retry attempts
        waitDuration: 1s            #A fixed wait duration between retry attempts
        retryExceptions:            #Configures a list of error classes that are recorded as a failure and thus are retried
          - com.example.exception.ExternalApiException
        ignoreExceptions:           #Configures a list of error classes that are ignored and thus are not retried.
          - com.example.exception.ResourceNotFoundException
    instances:
      defaultConfig:
        base-config: default
      advanceConfig:
        base-config: default
        waitDuration: 500ms # 기본 설정에 override
  • retry관련 로깅을 하고 싶다면 다음과 같은 빈을 들록하면 된다.
@Configuration
class ResilienceConfig : Log {

    @Bean
    fun retryEventConsumer(): RegistryEventConsumer<Retry> {
        return object : RegistryEventConsumer<Retry> {
            override fun onEntryAddedEvent(entryAddedEvent: EntryAddedEvent<Retry>) {
                entryAddedEvent.addedEntry.eventPublisher.onEvent { event -> log.info(event.toString()) }
            }
        }
    }
}
  • 재시도 적용의 경우 AOP가 적용된 애노테이션을 이용한다.
@Service
class ExternalApiService(
    private val externalClients: ExternalClient
) : Log{
    companion object {
        const val DEFAULT_RETRY_CONFIG = "advanceConfig" // yaml에 설정한 config 명을 명시한다.
        const val ADVANCED_RETRY_CONFIG = "advancedConfig"
    }

    @Retry(name = DEFAULT_RETRY_CONFIG, fallbackMethod = "fallback")
    fun requestApi(request: String): String {
        return externalClients.requestEx(request)
    }
    
    @Retry(name = ADVANCED_RETRY_CONFIG, fallbackMethod = "fallback")
    fun requestApi2(request: String): String {
        return externalClients.requestEx(request)
    }

    private fun fallback(request: String, ex: ExternalApiException): String{
        log.info("request : {}, targetUrl : {}", request, ex.serviceUrl)
        return "api request to ${ex.serviceUrl} fail"
    }
}
  • fallback 메소드의 파라미터는 exception을 제외하고는 재시도 대상이 되는 메소드 파라미터와 일치해야 한다. 리턴타입 역시 일치해야 한다.
  • 위 재시도 설정에 따라 아래와 같이 재시도 후 fallback메소드를 수행한다
2024-08-23T00:02:49.799+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalClientA                          : request to www.google.com fail, param : Aaa
2024-08-23T00:02:49.805+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ResilienceConfig$$SpringCGLIB$$0         : 2024-08-23T00:02:49.804620300+09:00[Asia/Seoul]: Retry 'advanceConfig', waiting PT0.5S until attempt '1'. Last attempt failed with exception 'com.example.exception.ExternalApiException: 알 수 없는 서버 에러입니다'.
2024-08-23T00:02:50.315+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalClientA                          : request to www.google.com fail, param : Aaa
2024-08-23T00:02:50.316+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ResilienceConfig$$SpringCGLIB$$0         : 2024-08-23T00:02:50.315184500+09:00[Asia/Seoul]: Retry 'advanceConfig', waiting PT0.5S until attempt '2'. Last attempt failed with exception 'com.example.exception.ExternalApiException: 알 수 없는 서버 에러입니다'.
2024-08-23T00:02:50.822+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalClientA                          : request to www.google.com fail, param : Aaa
2024-08-23T00:02:50.823+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ResilienceConfig$$SpringCGLIB$$0         : 2024-08-23T00:02:50.822507400+09:00[Asia/Seoul]: Retry 'advanceConfig', waiting PT0.5S until attempt '3'. Last attempt failed with exception 'com.example.exception.ExternalApiException: 알 수 없는 서버 에러입니다'.
2024-08-23T00:02:51.329+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalClientA                          : request to www.google.com fail, param : Aaa
2024-08-23T00:02:51.330+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ResilienceConfig$$SpringCGLIB$$0         : 2024-08-23T00:02:51.330199100+09:00[Asia/Seoul]: Retry 'advanceConfig', waiting PT0.5S until attempt '4'. Last attempt failed with exception 'com.example.exception.ExternalApiException: 알 수 없는 서버 에러입니다'.
2024-08-23T00:02:51.834+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalClientA                          : request to www.google.com fail, param : Aaa
2024-08-23T00:02:51.836+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ResilienceConfig$$SpringCGLIB$$0         : 2024-08-23T00:02:51.835502100+09:00[Asia/Seoul]: Retry 'advanceConfig' recorded a failed retry attempt. Number of retry attempts: '5'. Giving up. Last exception was: 'com.example.exception.ExternalApiException: 알 수 없는 서버 에러입니다'.
2024-08-23T00:02:51.836+09:00  INFO 24520 --- [demo] [nio-8080-exec-1] ExternalApiService                       : request : Aaa, targetUrl : www.google.com

올리브영 테크블로그

0개의 댓글

Powered by GraphCDN, the GraphQL CDN