본문 바로가기

JAVA

[Apache] CloseableHttpClient 사용 시 try-with-resources문으로 리소스 관리

반응형

✅개요

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());
    }
}

 

 

★ 위 코드의 문제점

  1. 예외 발생 시 리소스가 해제되지 않음
  2. response도 명시적으로 닫아주지 않음
  3. 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