✅개요
HTTP 통신을 구현할 때 Apache의 CloseableHttpClient는 매우 유용한 도구입니다.
하지만 네트워크 리소스를 사용하는 만큼, 적절한 자원 관리가 매우 중요합니다.
물론, 트래픽이 늘어날수록 리소스를 적절하게 사용하지 않으면 에러가 발생하게 됩니다.
이번 글에서는 try-with-resources를 활용한 올바른 리소스 관리 방법에 대해 알아보겠습니다.
✅CloseableHttpClient와 리소스 관리의 중요성
CloseableHttpClient는 네트워크 연결, 스레드 풀 등 여러 시스템 리소스를 사용합니다.
이러한 리소스들이 제대로 해제되지 않으면 다음과 같은 문제가 발생할 수 있습니다:
- 메모리 누수
- 네트워크 연결 고갈
- 시스템 성능 저하
- 최악의 경우 애플리케이션 크래시
✅ 잘못된 사용 예시
public class BadExample {
public String getDataFromApi(String url) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(request);
// 리소스 누수 가능성이 있는 코드
return EntityUtils.toString(response.getEntity());
}
}
★ 위 코드의 문제점
- 예외 발생 시 리소스가 해제되지 않음
- response도 명시적으로 닫아주지 않음
- httpClient가 제대로 종료되지 않음
✅사용 방법
1. try-with-resources 활용
public class GoodExample {
public String getDataFromApi(String url) throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(new HttpGet(url))) {
return EntityUtils.toString(response.getEntity());
}
}
}
2. 커스텀 설정을 포함한 완성된 예제
public class CompleteExample {
public String getDataWithCustomConfig(String url) throws IOException {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.build();
try (CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
CloseableHttpResponse response = httpClient.execute(new HttpGet(url))) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
}
}
✅주요 이점
- 자동 리소스 관리
- try 블록을 벗어나면 자동으로 close() 메소드 호출
- 예외 발생 시에도 안전하게 리소스 해제
- 코드 가독성
- 명시적인 finally 블록 불필요
- 리소스 관리 의도가 명확히 드러남
- 안정성 향상
- 실수로 인한 리소스 누수 방지
- 예외 처리의 단순화
✅실무 활용 팁
1. 싱글톤 패턴과 함께 사용
public class HttpClientManager {
private static final CloseableHttpClient httpClient = HttpClients.custom()
.setMaxConnTotal(100)
.setMaxConnPerRoute(20)
.build();
public static CloseableHttpClient getHttpClient() {
return httpClient;
}
// 애플리케이션 종료 시 호출
public static void closeHttpClient() {
try {
httpClient.close();
} catch (IOException e) {
// 로깅 처리
}
}
}
2. 스프링 빈으로 관리
보통 스프링을 사용하니까, Bean으로 관리하는게 편할 수 있습니다.
@Configuration
public class HttpClientConfig {
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.custom()
.setMaxConnTotal(100)
.setMaxConnPerRoute(20)
.build();
}
}
✅결론
CloseableHttpClient를 사용할 때는 반드시 적절한 리소스 관리가 필요합니다.
try-with-resources를 활용하면 안전하고 효율적으로 리소스를 관리할 수 있으며, 이는 애플리케이션의 안정성과 성능 향상에 큰 도움이 됩니다.
실무에서는 상황에 따라 싱글톤 패턴이나 스프링 빈으로 관리하는 방식도 고려해 볼 수 있으며,
항상 리소스의 수명 주기를 고려한 설계가 필요합니다.
'JAVA' 카테고리의 다른 글
JAVA로 만드는 간단한 HTTP Client 튜토리얼 (2) | 2025.01.10 |
---|