관리 메뉴

bright jazz music

RestTemplate 02 : 커넥션 풀(connection pool) 추가 본문

Framework/Spring

RestTemplate 02 : 커넥션 풀(connection pool) 추가

bright jazz music 2023. 3. 6. 10:19

RestTemplate은 HTTPClient를 추상화 한다.

HttpClient에는 여러 종류가 있으며, RestTemplate이 추상화 하는 HTTPTemplate은 RestTemplate은 기본적으로 커넥션 풀을 제공하지 않는다.

커넥션 풀 기능을 제공하지 않으면 매번 호출할 때마다 포트를 열어 커넥션을 생성한다.

따라서 TIME_WAIT 상태가 된 소켓을 사용하려고 접근하여도 재사용할 수 없다.

 

커넥션 풀 기능을 활성화 하는 가장 대표적인 방법은 HTTPClient가 추상화 하는 HTTPClient를 아파치에서 제공하는 HTTPClient로 대체하여 사용하는 것이다.

 

1. 아파치 HttpClient 의존성 추가

//build.gradle
dependencies {


    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
    implementation 'org.apache.httpcomponents:httpclient'

    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore
    implementation 'org.apache.httpcomponents:httpcore'

    
    /*    아래 라이브러리와는 메서드에 차이가 있다.
    // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
	implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'    */
}

 

 

2. 구현

//RestTemplateConnPoolService.java

package com.project.base.service;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


@Service
public class RestTemplateConnPoolService {

    public RestTemplate restTemplate(){

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();

        HttpClient Client = HttpClientBuilder.create()
                .setMaxConnTotal(500)	//최대 오픈되는 커넥션 수
                .setMaxConnPerRoute(500)	//IP, 포트 1쌍에 대해 수행할 커넥션 수
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setMaxConnTotal(500)
                .setMaxConnPerRoute(500)
                .build();

        factory.setHttpClient(httpClient);
        factory.setConnectTimeout(2000);	//2000ms(=2초)가 지나면 타임아웃
        factory.setReadTimeout(5000);	//5000ms(=5초)가 지나면 타임아웃

        //ClientHttpRequestFactory 인터페이스를 구현한 HttpComponentsClientHttpRequestFactory클래스의 객체를 넣어준다.
        RestTemplate restTemplate = new RestTemplate(factory);

        return restTemplate;
    }
}

 

RestTemplate의 생성자 중에는 ClinetHttpRequestFactory를 매개변수로 받는 생성자가 존재한다.

ClientHttpRequestFactory는 함수형 인터페이스(functional Interface)이다.

 

ClientHttpRequestFactory 인터페이스의 대표적인 구현체

  • SimpleClientHttpRequestFactory (기본값)
  • HttpComponentsClientHttpRequestFactory

별도의 구현체를 설정해서 전달하지 않는 경우 SimpleClientHttpRequestFactory를 사용한다. 

(이 내용은 import org.springframework.http.client.support.HttpAccessor에 기재돼 있다.)

 

위 코드에서는 SimpleClientHttpRequestFactory가 사용되지 않았다.

위 HttpComponentsClientHttpRequestFactory를 선언하여 RestTemplate()의 매개변수로 사용했기 때문이다.

 

HttpComponentsClientHttpRequestFactory를 사용하면

  • RestTemplate의 Timeout을 설정할 수 있다.
  • 커넥션 풀을 설정하기 위해 HttpClient를 HttpComponentsClientHttpRequestFactory에 설정할 수 있다. ( .setHttpClient() )

HttpClient를 생성하는 방법은 두 가지가 있다.

  • HttpClientBuilder.create()
  • HttpClients.custom()

 

이렇게 설정한 HttpComponentsClientHttpRequestFactory객체를 RestTemplate을 초기화 하는 과정에 인자로 전달한다.

 

 

---

 

 

 

setConnectTimeout and setReadTimeout

https://www.baeldung.com/java-socket-connection-read-timeout

 

Connection Timeout

: 클라이언트가 소켓을 사용하여 호스트에 연결을 시도하는 동안 블로킹이 되어 다른 작업이 중단된다.

띠라서 일정 시간이 지나도 연결에 성공하지 못하면 connection timeout을 해줘야 한다.

 

서버 측에서도 서버 소켓이 커넥션 요청을 받을 경우 accept() 메소드를 사용하여 소켓 객체를 생성한다.이 메소드 역시 원격 클라이언트와의 커넥션에 성공할 때까지 블로킹 한다.

 

Read Timeout

: 소켓으로부터 최소 1 바이트를 읽어들일 때까지 블로킹한다. 따라서 타임아웃을 정해줘야 한다.

 

 

커넥션 풀?

https://www.baeldung.com/java-connection-pooling

 

HttpClient와 CloseableHttpClient의 차이

https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient

 

 

 

Comments