Java&Web

[WEB] RestTemplate의 Connection Pool 설정

프로그래민 2021. 4. 24. 11:47
반응형

2021.01.23 - [Java&Web] - [WEB] RestTemplate을 이용하여 API 호출하기

 

[WEB] RestTemplate을 이용하여 API 호출하기

RestTemplate이란? RestTemplate은 Spring 3.0 부터 지원하는 템플릿으로 Spring에서 HTTP 통신을 RESTful 형식에 맞게 손쉬운 사용을 제공해주는 템플릿이다. Rest API 서비스를 요청후 응답 받을 수 있도록 설계.

minkwon4.tistory.com

 

RestTemplate의 Connection Pool이란

Spring 3.0부터 지원하는 HTTP 통신 템플릿인 RestTemplate은 복잡한 HttpClient 사용을 한번 추상화한 객체로써 단순 메소드 호출만으로 쉽게 HTTP 요청을 주고 받을 수 있도록 도와준다. RestTemplate은 호출할 때마다, 로컬에서 임시 TCP 소켓을 개방하여 사용한다. 이렇게 사용된 TCP 소켓은 TIME_WAIT 상태가 되는데, 요청량이 많아진다면 TIME_WAIT 상태의 소켓들은 재사용 될 수 없기 때문에 응답에 지연이 생길 수 있다. 이러한 응답 지연 상황을 대비하여 DB가 Connection Pool을 이용하듯이 RestTemplate도 Connection Pool을 이용할 수 있다. 그러기 위해선 RestTemplate 내부 구성을 설정해줘야한다.

단, 호출하는 API 서버가 Keep-Alive를 지원해야지 RestTemplate의 Connection Pool을 활용할 수 있다. 타겟 서버가 Keep-Alive를 지원하지 않는다면 미리 Connection Pool을 만들어 놓지 못하고 요청마다 새로운 Connection이 연결되어 매번 핸드쉐이크가 발생된다. 따라서 Connection Pool을 위한 RestTemplate의 내부 설정이 무의미하게 된다.

 

RestTemplate의 Connection Pool 설정

RestTemplate 객체를 생성할때 별도의 파리미터 없이 new RestTempalte()으로 생성한다면 Connection Pool을 활용하지 않는 객체이다. Connection Pool의 설정을 하기 위해선 객체를 생성할 때 인자로써 ClientHttpRequestFactory의 구현체를 사용해야 한다. 링크(RestTemplate). 간단한 Connection Pool 설정을 추가하여 Bean으로 등록하면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Configuration
public class RestTemplateConfig {
    @Bean
    HttpClient httpClient() {
        return HttpClientBuilder.create()
            .setMaxConnTotal(100)    //최대 오픈되는 커넥션 수
            .setMaxConnPerRoute(5)   //IP, 포트 1쌍에 대해 수행할 커넥션 수
            .build();
    }
 
    @Bean
    HttpComponentsClientHttpRequestFactory factory(HttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(5000);        //읽기시간초과, ms
        factory.setConnectTimeout(3000);     //연결시간초과, ms
        factory.setHttpClient(httpClient);
 
        return factory;
    }
 
    @Bean
    RestTemplate restTemplate(HttpComponentsClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }
}
 

Connection 수에 관한 설정을 담은 HttpClient 객체를 생성하고, 이 HttpClient를 이용하여 Connection 시간 설정과 함께 HttpComponetsClientHttpRequestFactory 객체를 생성한다. 그 후 RestTemplate의 생성자 인자인 ClientHttpRequestFactory의 구현체로써 HttpComponetsClientHttpRequestFactory 객체를 사용하여 주입을 시켜주었다. 

또는 RequestConfig와 PoolingHttpClientConnectionManager을 활용하여 다음과 같이 설정을 할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Configuration
public class RestTemplateConfig {
    @Bean
    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100);                    //최대 오픈되는 커넥션 수
        connectionManager.setDefaultMaxPerRoute(5);            //IP, 포트 1쌍에 대해 수행할 커넥션 수
 
        return connectionManager;
    }
 
    @Bean
    public RequestConfig requestConfig() {
        return RequestConfig.custom()
            .setConnectionRequestTimeout(3000)        //연결요청시간초과, ms
            .setConnectTimeout(3000)                //연결시간초과, ms
            .setSocketTimeout(3000)                    //소켓시간초과, ms
            .build();
    }
 
    @Bean
    public CloseableHttpClient httpClient(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager, RequestConfig requestConfig) {
        return HttpClientBuilder
            .create()
            .setConnectionManager(poolingHttpClientConnectionManager)
            .setDefaultRequestConfig(requestConfig)
            .build();
    }
 
    @Bean
    public RestTemplate restTemplate(HttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
 
        return new RestTemplate(requestFactory);
    }
}
 

더 다양한 설정은 링크(HttpClientBuilder), 링크(HttpComponentsClientHttpRequestFactory)에서 확인 후 설정해줄 수 있다.

 

출처
sjh836.tistory.com/141
skasha.tistory.com/48
multifrontgarden.tistory.com/249
jodu.tistory.com/46
coding-start.tistory.com/185
반응형