-
api retry하기개발/java 2024. 8. 28. 13:06
msa 구조 내에서는 api 통신이 빈번하게 발생한다.
그중 gateway 관련된 오류의 경우 일시적인 경우가 많기에 재시도를 하면 해소 되는 경우가 많다
그러므로 해당 api의 응답코드(httpStatusCode)가 502 ,504인 경우 재호출을 하여 오류 빈도를 줄일 수 있다.
재시도의 경우 아래와 같이 HttpClient 내부에서 제공하는 HttpRequestRetryHandler를 이용하는 방법이 대표적이다.
HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> { if (executionCount > 3) { // retry의 maxCount를 설정하여 false를 return 하면 재시도가 중단된다 return false; } if (exception instanceof IOException) { // 특정 Exception이 발생할 때 true를 반환하면 retry를 수행한다 return true; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpUriRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); return idempotent; }; CloseableHttpClient client = HttpClients.custom() .setRetryHandler(retryHandler) .build(); HttpUriRequest request = new HttpGet("http://localhost:8080"); HttpResponse response = client.execute(request); HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity); System.out.println(result); }
그러나 보통 Client의 경우 규모가 클 경우 공통 msa 내에서 파이를 가져가기에 직접 HttpClient를 수정하기 어려운 경우가 있다.
이 경우 HttpClient를 받을 때 intercepter를 통해 조작을 할 수 있다.
RestTemplate의 경우 interceptor의 메소드를 통해 intercepter를 등록할 수 있다.
RetryTemplate retryTemplate; HttpRequestInterceptor httpRequestInterceptor; retryTemplate.getInterceptors().add(httpRequestInterceptor); public class HttpRequestInterceptor implement ClientHttpRequestInterceptor{ @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { RetryTemplate retryTemplate = new RetryTemplate(); Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>(); retryableExceptions.put(HttpServerErrorException.class, true); //HttpServerErrorException일 경우 재시도 max 2회 수행 SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(2, retryableExceptions); retryTemplate.setRetryPolicy(retryPolicy); //재시도를 수행한다 return retryTemplate.execute(retryContext->{ ClientHttpResponse response = execution.execute(request, body); if(response.getRawStatusCode()==502){ throw new HttpServerErrorException(response.getStatusCode()); } }) } }
'개발 > java' 카테고리의 다른 글
mybatis로 jpa 흉내내기 (3) 2024.09.03 싱글턴 문제점과 해결책 (0) 2024.09.02 Exception 분리 (0) 2024.08.19 RESTAPI 이력감지 (0) 2024.08.19 map vs flatmap (0) 2022.01.04