RestTemplate 사용시 주의사항

최근에 RestTemplate을 사용하면서 겪은 장애상황과 해결포인트에 대해 간략히 정리해 보았다.

발단

jetty를 이용한 웹서비스에서 다른 백엔드 컴포넌트의 rest api를 호출하는 부분의 구현방식을

변경해야 할 요구사항이 생겼다.

총 api 호출횟수는 (해당 사용자의 총 데이터 수 / 100)로 데이터가 많은 유저일수록

api호출횟수가 늘어났고, 전보다 rest api의 응답속도가 빨라져 단위시간당 api 호출횟수가

더 많아진 상황이었다.

이 부분에 RestTemplate을 적용해 배포하고, 대략 20분 뒤 웹서비스의 응답이 급격히

느려지면서 access log의 요청횟수가 평소의 절반으로 떨어지기 시작했다.

그리고 VisualVM으로 해당서버를 모니터링 해보니 jetty의 worker thread가 평소와 다르게

계단 모양으로 증가하는 추세를 보였다.

문제원인 분석

일단 의심스러운 구간별로 처리시간을 로그로 남겨 확인해 본 결과, 예상대로 RestTemplate으로

rest api를 호출하는 부분이 오래 걸리는 것을 데이터로 확인했다.

그리고 해당서버의 시스템리소스를 확인해보니, 유독 tcp connection 갯수가 평소의 적게는 3배

많게는 8배까지 증가한 걸 확인할 수 있었다.

그렇다면 왜 tcp connection이 갑자기 급격하게 증가했을까?

해결포인트

앞서 언급했듯이 호출횟수도 많긴 하지만 그보다 RestTemplate은 기본적으로 connection

pooling을 하지 않기 때문에, 매 요청마다 새로운 로컬포트를 열어서 서버로의 커넥션을

생성하게 된다. 이로 인해 tcp connection이 급격하게 증가하게 되었고,

이를 해결하기 위해 아래와 같이 connection pooling관련 설정을 추가한 HttpClient객체를

HttpComponentsClientHttpRequestFactory에 주입해 해결했다.

HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(xxx);
httpRequestFactory.setReadTimeout(xxx);
<strong>HttpClient httpClient = HttpClientBuilder.create()
 .setMaxConnTotal(xxx)
 .setMaxConnPerRoute(xxx)
 .build();
httpRequestFactory.setHttpClient(httpClient);</strong>
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);

여기서 중요한 건,  HttpClient의 maxConnTotal과 maxConnPerRoute인데 이에 대한

설명은 https://stackoverflow.com/a/31892901 에서 확인하면 된다.

maxConnTotal과 maxConnPerRoute 갯수는 각 서비스의 상황에 맞게 적절한 값을

넣어주면 된다.

내가 겪은 상황이 일반적인 상황은 아니지만, 혹시나 비슷한 상황하에 RestTemplate을

사용한다면 꼭 connection pooling 설정추가를 고려해 보았으면 한다.

참고로, 아래링크는 최대 커넥션 수에 영향을 주는 클라이언트/서버관련 사항들이다.

https://stackoverflow.com/a/3923785

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중