본문 바로가기

개발/Java & Spring

[Spring] spring-retry로 요청을 재전송한다 한다 한다맨 - 개발일기 C[3]


우와 챗 봇도 개발 거의 끝났는데 꼴랑 3번째라니.

괜찮아요 ,, 협업이 목적이었으니까용 ,, 



그래도 새로운거 하나 얻어간다! 


내 담당 모듈은 

"실시간 지하철 위치 정보 제공" 모듈인데

여기서 "실시간" 이라는 특성때문에, 공공 데이터 API 서버거 정말 자주 죽었다.


아니 공공 API 맞아 ? 싶을정도로. 다른 어플도 여기서 받아다 쓸텐데 정말 이렇게 자주 죽는다고? 싶을 정도로. 10번중 4번은 죽는다 진심으로 오버 아님.



온갖 고민을 해봤다.


주기적으로 모든 지하철역 정보를 불러와서 DB에 저장하고 서버가 죽으면 가장 최신의 정보를 불러올까? 

-> Batch를 공부해야할 것 같았다.(시간이없다 ㅠㅠ) 그리고 그 많은 역 정보 보관하면,,, 저 AWS 이제 회생신청도 못해요 흑흑 



어차피 상용화할 것은 아니니 DB에 조금만 넣을까?

-> 지금 당장 DB 안쓰기 때문에, 이걸로 DB 파는게 부담이 됐다.



한 세번정도 재요청하고 안되면 사과 메시지 전달해주면 안되나?

-> spring-retry! 



spring-retry는 원래 spring batch에서 제공하다가 spring v4 부터 제공해주는 것이라고 한다.


말그대로 재요청이다! 


레퍼런스 -> https://github.com/spring-projects/spring-retry


나는 요 Quick Start만 참고했다.


사용 전에, 아래의 의존을 추가해준다.

참고로 나는 버전 문제로 삽질 꽤나 오래했으니 일단은 이대로 하는 것을 추천 드립니다,, 버전 하나하나 바꿔가며 이룩해낸 나의 성과..



@Configuration
@EnableRetry
public class Application {

   @Bean
   public Service service() {
       return new Service();
  }

}

@Service
class Service {
   @Retryable(RemoteAccessException.class)
   public void service() {
       // ... do something
  }
   @Recover
   public void recover(RemoteAccessException e) {
      // ... panic
  }
}


이미 충분히 요약되어있지만, 더 요약하면

Configuration에 @EnableRetry 를 추가하면 spring-retry를 사용할 수 있다. 
그런다음, 재요청이 필요한 서비스(또는 모듈)에 @Retryable 를 추가한다.


밑에는 내 코드 

@Retryable(

      value = {NestedServletException.class, HttpServerErrorException.class }, 

      maxAttempts = 3)

public ResponseEntity<String> realAccessTimeData(String station) throws UnsupportedEncodingException,NestedServletException, HttpServerErrorException;

@Recover

    void recover(HttpServerErrorException e, String station);




마크다운 통으로 복사 안돼서 미치것다 ,, 

어쨋든 최대 3번까지 재시도 하도록 설정했고,

구현 함수에서 추가로 retry 횟수 출력하는 코드도 써놨다.



테스팅 해보면

(아오 그렇게 틈나면 나던 서버 에러가 테스팅 하려니까 안나네욤 ^_^ 50번은 실행한듯)




INFO : kr.ac.han.SubwayTest - /subway test before INFO : org.springframework.mock.web.MockServletContext - Initializing Spring FrameworkServlet '' INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization started INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization completed in 11 ms INFO : kr.ac.han.SubwayTest - /subway 호출 INFO : kr.ac.han.service.SubwayAPIDataServiceImpl - 0 -> 처음 실행 WARN : org.springframework.web.client.RestTemplate - GET request for "" resulted in 503 (Service Temporarily Unavailable); invoking error handler INFO : kr.ac.han.service.SubwayAPIDataServiceImpl - 1 -> 두 번째 실행


요렇게 1번 더 리트라이 해줬다!

물론 maxAttemp 만큼 더 하겠지만, 아쉽게도 한번만에 응답을 받아왔어욤 하하 



간단한 재요청은 쉽게 처리할 수 있을 것 같다.

새로운거 하나 배워가서 다행이다!