Retrying Feign Calls
소개
- REST 엔드포인트를 통해 외부 서비스를 호출하는 것은 Feign과 같은 라이브러리에서 매우 간단하게 작성할 수 있습니다.
- 그러나 이러한 호출 중에 많은 문제가 발생할 수 있습니다. 이러한 문제의 대부분은 무작위적이거나 일시적인 것입니다.
- 여기에서는 실패한 호출을 다시 시도하고 보다 탄력적인 REST 클라이언트를 만드는 방법에 대해 알아봅니다.
Spring Cloud OpenFeign 환경설정
dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:2022.0.1")
}
}
# application.properties
spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.response.enabled=true
spring.cloud.openfeign.client.config.default.logger-level=full
spring.cloud.openfeign.client.config.default.connect-timeout=5000
spring.cloud.openfeign.client.config.default.read-timeout=5000
Feign Retryer
Default Implementation
- Feign은 재시도 인터페이스의 합리적인 기본 구현을 제공합니다.
- 주어진 횟수만큼만 재시도하고, 일정 시간 간격으로 시작한 다음, 재시도할 때마다 지정된 최대값까지 간격을 늘립니다.
- 시작 간격을 1초, 최대 간격을 3초, 최대 시도 횟수를 3회로 정의해 보겠습니다:
@Configuration(proxyBeanMethods = false)
public class CustomOpenFeignConfig {
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(1000, TimeUnit.SECONDS.toMillis(3), 3);
}
}
No Retrying
- Feign이 호출을 재시도하지 않도록 하려면 클라이언트 빌더에 Retryer.NEVER_RETRY 구현을 제공하면 됩니다.
- 그러면 매번 예외를 전파하기만 하면 됩니다.
@Configuration(proxyBeanMethods = false)
public class CustomOpenFeignConfig {
@Bean
public Retryer feignNoRetryer() {
return Retryer.NEVER_RETRY;
}
}
Creating Retryable Exceptions
- 이전에는 호출을 재시도하는 빈도를 제어하는 방법을 배웠습니다.
- 이제 호출을 재시도할 때와 단순히 예외를 던질 때를 제어하는 방법을 살펴보겠습니다.
ErrorDecoder 와 RetryableException
- 잘못된 응답을 받으면 Feign은 이를 어떻게 처리할지 결정하는 ErrorDecoder 인터페이스의 인스턴스로 전달합니다.
- 가장 중요한 것은 디코더가 예외를 RetryableException의 인스턴스에 매핑하여 Retryer가 호출을 재시도할 수 있도록 한다는 점입니다.
- ErrorDecoder의 기본 구현은 응답에 "Retry-After" 헤더가 포함된 경우에만 RetryableException 인스턴스를 생성합니다. 가장 일반적으로 503 서비스 사용 불가 응답에서 찾을 수 있습니다.
- 이는 좋은 기본 동작이지만 때로는 더 유연해야 할 때도 있습니다.
- 예를 들어, 때때로 500 내부 서버 오류로 무작위로 응답하는 외부 서비스와 통신하고 있는데 이를 해결할 수 있는 권한이 없는 경우가 있습니다.
- 우리가 할 수 있는 일은 다음 번에는 통화가 성공할 것이라는 것을 알기 때문에 통화를 다시 시도하는 것입니다.
- 이를 위해서는 사용자 정의 ErrorDecoder 구현을 작성해야 합니다.
Custom Error Decoder 생성
- 사용자 정의 디코더에서 구현해야 하는 메서드는 decode 하나뿐입니다.
- 이 메서드는 두 개의 인자, 즉 String 메서드 키와 Response 객체를 받습니다.
- 이 메서드는 예외를 반환하는데, 이 예외가 RetryableException의 인스턴스이거나 구현에 따라 다른 예외인 경우 예외를 반환합니다.
- 디코딩 메서드는 단순히 응답의 상태 코드가 500보다 높거나 같은지 확인합니다.
- 이 경우 RetryableException을 생성합니다. 그렇지 않은 경우, FeignException 클래스의 errorStatus 팩토리 함수로 생성된 기본 FeignException을 반환합니다:
public class Custom5xxErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
FeignException exception = feign.FeignException.errorStatus(methodKey, response);
int status = response.status();
if (status >= 500) {
return new RetryableException(
response.status(),
exception.getMessage(),
response.request().httpMethod(),
exception,
null,
response.request());
}
return exception;
}
}
Custom Error Decoder 설정 추가
@Configuration(proxyBeanMethods = false)
public class CustomOpenFeignConfig {
@Bean
public ErrorDecoder custom5xxErrorDecoder() {
return new Custom5xxErrorDecoder();
}
}
'SpringBoot' 카테고리의 다른 글
Kotlin Simple Version Compare (0) | 2023.03.21 |
---|---|
Spring 6 의 HTTP Interface (0) | 2023.03.14 |
RedisTemplate 과 Json Serializer 설정 (0) | 2019.07.09 |
MongoDB _class 필드 제거하기 (0) | 2019.07.09 |
restful json request response 패킷 로깅 필터 (1) | 2019.07.04 |