RestTemplate
- Spring์์ ์ ๊ณตํ๋ Rest Client
 - ํ์ฌ๋ Deprecated๋์ด 
WebClient๋ก ๊ฐ์ด๋๋ฅผ ํ๊ณ ์๋ค. 
NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.
์ฃผ์ํ ์ ์ ์์๊น?
- ๋ง์ ์์ฒญ๋ค์ ๋ค๋ฃจ๊ธฐ ์ด๋ ต๋ค.
- RestTemplate๋ ๊ธฐ๋ณธ์ ์ผ๋ก Connection pool์ ์ฌ์ฉํ์ง ์๋๋ค.
 - Default๋ก 
java.net.HttpURLConnection์ฌ์ฉํ๋ค.- SimpleClientHttpRequestFactory
 
 - ๊ทธ๋์ ๋ง์ ์์ฒญ์ ํ๋ฉด 
TIME_WAIT๋ก ์ธํด ์์์ด ์ ์  ๋ถ์กฑํด์ ธ ์๋น์ค์ ์ด๋ ค์์ ๊ฐ์ ธ์จ๋ค. - ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Connection Pool์ ๋ง๋ค์ด ์ฌ์ฉํ๊ธฐ๋ฅผ ๊ถ์ฅํ๊ณ ์๋ค.
 
 
์ด๋ป๊ฒ Connection Pool์ ์ฌ์ฉํ ์ ์์๊น?
CloseableHttpClient httpClient = HttpClientBuilder.create()
    .setMaxConnTotal(120) // maxConnTotal์ ์ฐ๊ฒฐ์ ์ ์งํ  ์ต๋ ์ซ์
    .setMaxConnPerRoute(60) // maxConnPerRoute๋ ํน์  ๊ฒฝ๋ก๋น ์ต๋ ์ซ์
    .setConnectionTimeToLive(5, TimeUnit.SECONDS) // keep - alive
    .build();
 
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(5000); // ์ฝ๊ธฐ์๊ฐ์ด๊ณผ, ms
factory.setConnectTimeout(3000); // ์ฐ๊ฒฐ์๊ฐ์ด๊ณผ, ms
factory.setHttpClient(httpClient); // ๋๊ธฐ์คํ์ ์ฌ์ฉ๋  HttpClient ์ธํ
 
this.restTemplate = new RestTemplate(factory);Springboot์์๋ ์ด๋ป๊ฒ ๋ ์ฝ๊ฒ ๋ง๋ค ์ ์์๊น?
RestTemplateCustomizer๋ฅผ ํ์ฉํ๋ฉด ์ฝ๊ฒ Custom ํ ์ ์๋ค.ResponseErrorHandler๋ฅผ ํ์ฉํ์ฌ error ํธ๋ค๋ง๋ ๋ถ๋ฆฌํ ์ ์๋ค.- RestTemplateBuilder Doc
 - Springboot RestTemplateBuilder
 
CloseableHttpClient httpClient = HttpClientBuilder.create()
    .setMaxConnTotal(120) // maxConnTotal์ ์ฐ๊ฒฐ์ ์ ์งํ  ์ต๋ ์ซ์
    .setMaxConnPerRoute(60) // maxConnPerRoute๋ ํน์  ๊ฒฝ๋ก๋น ์ต๋ ์ซ์
    .setConnectionTimeToLive(5, TimeUnit.SECONDS) // keep - alive
    .build();
 
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient); // ๋๊ธฐ์คํ์ ์ฌ์ฉ๋  HttpClient ์ธํ
 
 this.restTemplate = new RestTemplateBuilder()
    .rootUri("https://nesoy.github.io")
    .requestFactory(() -> factory)
    .setConnectTimeout(Duration.ofSeconds(3))
    .setReadTimeout(Duration.ofSeconds(5))
    .errorHandler(new RestResponseErrorHandler()) // ResponseErrorHandler interface
    .build();ResponseErrorHandler๋ฅผ ์์๋ฐ์๋ ๋์ง๋งDefaultResponseErrorHandlerํ๋ฉด ์ฝ๊ฒ ํ ์ ์๋ค.
 public class RestResponseErrorHandler extends DefaultResponseErrorHandler {
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            log.error("Has error response: {}", response);
            super.handleError(response);
        }
 
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            log.error("Has error response: {}", response);
            return super.hasError(response);
        }
    }Reference
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
 - https://taetaetae.github.io/2018/03/17/rest-client-exception/
 - https://blog.advenoh.pe.kr/spring/%EC%8A%A4%ED%94%84%EB%A7%81-RestTemplate/
 - https://sjh836.tistory.com/141
 - https://stackoverflow.com/questions/31869193/using-spring-rest-template-either-creating-too-many-connections-or-slow
 - https://taes-k.github.io/2019/11/27/spring-java-connections/
 - https://inyl.github.io/programming/2017/09/14/http_component.html
 - https://github.com/ihoneymon/rest-template-of-spring