Spring - RestTemplate Connection Pooling

2019. 6. 13. 22:30Web/Spring

 

오늘 포스팅할 내용은 Spring의 RestTemplate입니다. 우선 RestTemplate란 Spring 3.0부터 지원하는 Back End 단에서 Http 통신에 유용하게 쓰이는 템플릿 객체이며, 복잡한 HttpClient 사용을 한번 추상화하여 Http 통신사용을 단순화한 객체입니다. 즉, HttpClient의 사용에 있어 기계적이고 반복적인 코드들을 한번 랩핑해서 손쉽게 사용할 수 있게 해줍니다. 또한 json,xml 포멧의 데이터를 RestTemplate이 직접 객체에 컨버팅해주기도 합니다.

 

이렇게 사용하기 편한 RestTemplate에서도 하나 짚고 넘어가야할 점이 있습니다. RestTemplate 같은 경우에는 Connection Pooling을 직접적으로 지원하지 않기 때문에 매번 RestTemplate를 호출할때마다, 로컬에서 임시 TCP 소켓을 개방하여 사용합니다. 또한 이렇게 사용된 TCP 소켓은 TIME_WAIT 상태가 되는데, 요청량이 엄청 나게 많아진다면 이러한 상태의 소켓들은 재사용 될 수 없기 때문에 응답이 지연이 될것입니다. 하지만 이러한 RestTemplate도 Connection Pooling을 이용할 수 있는데 이것은 바로 RestTemplate 내부 구성에 의해 가능합니다. 바로 내부적으로 사용되는 HttpClient를 이용하는 것입니다. 바로 예제 코드로 들어가겠습니다.

 

우선 Connection pool을 적용하기 위한 HttpClientBuilder를 사용하기 위해서는 dependency 라이브러리가 필요하다.

 

compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'

 

각자 필요한 버전을 명시해서 의존성을 추가해준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    /*
     * Connection Pooling을 적용한 RestTemplate
     */
    @Bean(name="restTemplateClient")
    public RestTemplate restClient() {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        /*
         * 타임아웃 설정
         */
        //httpRequestFactory.setConnectTimeout(timeout);
        //httpRequestFactory.setReadTimeout(timeout);
        //httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
        HttpClient httpClient = HttpClientBuilder.create()
                                                 .setMaxConnTotal(150)
                                                 .setMaxConnPerRoute(50)
                                                 .build();
        httpRequestFactory.setHttpClient(httpClient);
        
        return new RestTemplate(httpRequestFactory);
    }
cs

 

위에 코드를 보면 최대 커넥션 수(MaxConnTotal)를 제한하고 IP,포트 1쌍 당 동시 수행할 연결 수(MaxConnPerRoute)를 제한하는 설정이 포함되어있습니다. 이런식으로 최대 커넥션 수를 150개로 제한하여 150개의 자원내에서 모든 일을 수행하게 되는 것입니다. 마치 DB의 Connection Pool 과 비슷한 역할이라고 보시면 됩니다.(물론 같지는 않음.) 그리고 RestTemplate은 Multi Thread 환경에서 safety 하기 때문에 빈으로 등록하여 가져다 쓰도록 하였습니다. 

 

마지막으로 구글링을 하던 도중에 Keep-alive 활성화가 되야지만 HttpClient의 Connection Pooling 지원이 가능하다고 나와있습니다. 기본적으로 HTTP1.1은 Keep-alive가 활성화되어 있지만 이부분은 더 깊게 알아봐야할 점인것 같습니다. 만약 해당 부분에 대해 아시는 분은 꼭 댓글에 코멘트 부탁드리겠습니다.