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