From 61d71de30038be6d3cca094b5b54887e18d8134a Mon Sep 17 00:00:00 2001 From: 101 Date: Fri, 13 Sep 2024 19:28:09 +0900 Subject: [PATCH] add: 5xx error retry strategy --- .../feign/Custom5xxErrorDecoder.java | 27 +++++++++++++ .../feign/Custom5xxRetryer.java | 38 +++++++++++++++++++ .../infrastructure/xquare/XquareClient.java | 2 +- .../xquare/XquareRetryConfiguration.java | 22 +++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxErrorDecoder.java create mode 100644 src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxRetryer.java create mode 100644 src/main/java/com/repo/whopper/infrastructure/xquare/XquareRetryConfiguration.java diff --git a/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxErrorDecoder.java b/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxErrorDecoder.java new file mode 100644 index 00000000..0a1f7d07 --- /dev/null +++ b/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxErrorDecoder.java @@ -0,0 +1,27 @@ +package com.repo.whopper.infrastructure.feign; + +import feign.Response; +import feign.RetryableException; +import feign.codec.ErrorDecoder; + +public class Custom5xxErrorDecoder implements ErrorDecoder { + private final ErrorDecoder defaultErrorDecoder = new Default(); + + @Override + public Exception decode(String methodKey, Response response) { + var exception = defaultErrorDecoder.decode(methodKey, response); + + if (response.status() >= 500) { + return new RetryableException( + response.status(), + exception.getMessage(), + response.request().httpMethod(), + exception, + (Long) null, + response.request() + ); + } + + return exception; + } +} \ No newline at end of file diff --git a/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxRetryer.java b/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxRetryer.java new file mode 100644 index 00000000..4809400c --- /dev/null +++ b/src/main/java/com/repo/whopper/infrastructure/feign/Custom5xxRetryer.java @@ -0,0 +1,38 @@ +package com.repo.whopper.infrastructure.feign; + +import feign.RetryableException; +import feign.Retryer; + +public class Custom5xxRetryer implements Retryer { + private final int maxAttempts; + private final long backoff; + private int attempt; + + public Custom5xxRetryer() { + this(2, 100L); + } + + public Custom5xxRetryer(int maxAttempts, long backoff) { + this.maxAttempts = maxAttempts; + this.backoff = backoff; + this.attempt = 1; + } + + @Override + public void continueOrPropagate(RetryableException e) { + if (attempt++ >= maxAttempts) { + throw e; + } + + try { + Thread.sleep(backoff); + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } + } + + @Override + public Retryer clone() { + return new Custom5xxRetryer(maxAttempts, backoff); + } +} diff --git a/src/main/java/com/repo/whopper/infrastructure/xquare/XquareClient.java b/src/main/java/com/repo/whopper/infrastructure/xquare/XquareClient.java index 34559caf..250d24ed 100644 --- a/src/main/java/com/repo/whopper/infrastructure/xquare/XquareClient.java +++ b/src/main/java/com/repo/whopper/infrastructure/xquare/XquareClient.java @@ -5,7 +5,7 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; -@FeignClient(name = "xquare-client", url = "${key.login-api-url}") +@FeignClient(name = "xquare-client", url = "${key.login-api-url}", configuration = XquareRetryConfiguration.class) public interface XquareClient { @PostMapping("/user-data") XquareUserResponse xquareUser(@RequestBody LoginRequest request); diff --git a/src/main/java/com/repo/whopper/infrastructure/xquare/XquareRetryConfiguration.java b/src/main/java/com/repo/whopper/infrastructure/xquare/XquareRetryConfiguration.java new file mode 100644 index 00000000..8354c753 --- /dev/null +++ b/src/main/java/com/repo/whopper/infrastructure/xquare/XquareRetryConfiguration.java @@ -0,0 +1,22 @@ +package com.repo.whopper.infrastructure.xquare; + +import com.repo.whopper.infrastructure.feign.Custom5xxErrorDecoder; +import com.repo.whopper.infrastructure.feign.Custom5xxRetryer; +import feign.Retryer; +import feign.codec.ErrorDecoder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +class XquareRetryConfiguration { + + @Bean + public Retryer retryer() { + return new Custom5xxRetryer(); + } + + @Bean + public ErrorDecoder errorDecoder() { + return new Custom5xxErrorDecoder(); + } +}