본문 바로가기
Spring

스프링 RestTemplate - Connection pool 설정 방법

by 쌩욱 2021. 10. 22.

1. RestTemplate?

  • spring 3.0 부터 지원
  • org.springframework.http.client
  • 복잡한 HttpClient 사용을 한번 추상화한 객체
    • HttpClient는 HTTP를 사용하여 통신하는 범용 라이브러리이고, RestTemplate은 HttpClient 를 추상화해서 제공
  • RESTful 원칙을 지키며 단순 메소드 호출만으로 쉽게 HTTP 요청을 주고 받을 수 있도록 도와주는 HTTP 통신 템플릿
  • RestTemplate 은 기본적으로 connection pool 을 사용하지 않는다.
    • RestTemplate은 호출할 때마다, 로컬에서 임시 TCP 소켓을 개방하여 사용한다.
    • 이렇게 사용된 TCP 소켓은 TIME_WAIT 상태가 되는데, 요청량이 많아지면 TIME_WAIT 상태의 소켓들은 재사용 될 수 없기 때문에 응답에 지연이 생김
    • 응답 지연 상황을 대비하여 Connection Pool을 이용할 수 있다.
  • ** Connection Pool을 설정하려면 API 서버가 Keep-Alive를 지원해야 한다.**

2. Connection pool 설정하기

  • Connection Pool의 설정을 하기 위해선 객체를 생성할 때 인자로 ClientHttpRequestFactory의 구현체를 사용해야 한다.
  • ClientHttpRequestFactory의 구현체인 HttpComponentsClientHttpRequestFactory를 사용할 예정이다.
  • RestTemplateConfig 클래스를 만들어 Connection pool을 설정하고 Bean으로 등록시켰다.
@Configuration
public class RestTemplateConfig {
    @Bean
    HttpClient httpClient() {
        return HttpClientBuilder.create()
                .setMaxConnTotal(100)    //최대 오픈되는 커넥션 수, 연결을 유지할 최대 숫자
                .setMaxConnPerRoute(30)   //IP, 포트 1쌍에 대해 수행할 커넥션 수, 특정 경로당 최대 숫자
                .build();
    }

    @Bean
    HttpComponentsClientHttpRequestFactory factory(HttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(5000);        
        factory.setConnectTimeout(3000);     
        factory.setHttpClient(httpClient);

        return factory;
    }

    @Bean
    RestTemplate restTemplate(HttpComponentsClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }
}
  • .setMaxConnTotal(100) : Connection을 유지할 수 있는 최대 숫자 설정
  • .setMaxConnPerRoute(30) : 한 개의 Route당 수행할 수 있는 Connection 최대 숫자 설정
  1. Connection 수에 관한 설정을 담은 HttpClient 객체를 생성
  2. 이 HttpClient를 이용하여 Connection 시간 설정과 함께 HttpComponetsClientHttpRequestFactory 객체를 생성
  3. 그 후 HttpComponetsClientHttpRequestFactory 객체를 사용하여 Restemplate에 주입을 시켜주었다.

 

* RestTemplate을 사용해 HTTP 요청 보내기 *

private final RestTemplate restTemplate; //DI
...
...
public void api(){
  	MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("KEY", VALUE);

    HttpHeaders headers = new HttpHeaders();
    headers.add("KEY",  VALUE);

    HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

    ResponseEntity<String> response = restTemplate.exchange(
        "{요청할 서버 주소}", 
        HttpMethod.POST, //{요청할 방식}
        entity, // {요청할 때 보낼 데이터}
        String.class //{요청시 반환되는 데이터 타입}
    );
 }

 

* RestTemplate 주요 메소드 *

RestTemplate Method HTTP Method 설명
execute Any  
exchange Any 헤더세팅해서 HTTP Method로 요청보내고 ResponseEntity로 반환받음
getForObject GET get 요청을 보내고 java object로 매핑받아서 반환받음
getForEntity GET get 요청을 보내고 ResponseEntity로 반환받음
postForLocation POST post 요청을 보내고 java.net.URI 로 반환받음
postForObject POST post 요청을 보내고 ResponseEntity로 반환받음
put PUT  
delete DELETE  
headForHeaders HEAD  
optionsForAllow OPTIONS  

 


3. Connection pool 적용이 잘 되나 확인하기

(1) yml 파일에 로그를 출력하도록 설정을 추가

  1. application.yml파일에 설정 추가
  2. logging: level: org: apache: http: DEBUG

(2) 로그를 통해 커넥션풀을 통해 Handshake가 처음에만 이루어지는지 확인

같은 API 요청을 여러 번 보냈을 때 handshake 과정을 한 번만 거치고 연결을 유지하는 것을 확인할 수 있다.

 

(3) API요청을 루프를 돌려 1500번 반복하고 소요된 시간을 측정해 성능 향상을 확인

 

Connection pool을 설정했을 때

MaxConnTotal 연결을 유지할 최대 숫자 100
MaxConnPerRoute 라우트당 최대 연결 숫자 100
API요청 1500번 실행 시 소요된 시간 91초

Connection pool을 적용하지 않았을 때

MaxConnTotal 연결을 유지할 최대 숫자 x
MaxConnPerRoute 라우트당 최대 연결 숫자 x
API요청 1500번 실행 시 소요된 시간 106초

1500번 정도만 실험했지만 시간이 줄어든 것을 확인 할 수 있었다.

 

(4) 성능 테스트 도구인 Apache Jmeter 사용해볼 예정

 

참고 출처

https://sjh836.tistory.com/141

 

RestTemplate (정의, 특징, URLConnection, HttpClient, 동작원리, 사용법, connection pool 적용)

참조문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html 1. RestTemplate이란? spring 3.0 부터 지원한다. 스프링에서 제공하는 http..

sjh836.tistory.com

https://minkwon4.tistory.com/216

 

[WEB] RestTemplate의 Connection Pool 설정

2021.01.23 - [Java&Web] - [WEB] RestTemplate을 이용하여 API 호출하기 [WEB] RestTemplate을 이용하여 API 호출하기 RestTemplate이란? RestTemplate은 Spring 3.0 부터 지원하는 템플릿으로 Spring에서 HTTP..

minkwon4.tistory.com