본문 바로가기
허브 살리기 프로젝트

Feign Client Connection Pool

by jay-choe 2024. 3. 25.

 

Feign Client를 무작정 사용하면 알아서 커넥션 풀을 사용할까?

 

알아서 사용 했으면 이렇게 글로 정리 하지도 않았을 것이다.

 

우선 커넥션 풀을 사용 할 필요가 있는 서비스와 사용 할 필요가 없는 서비스를 두 가지 유형으로 분리해보면

 

기준은 '자원' 이 될 것이다. (이 안에는 시간과 물리적인 자원이 포함된다.)

 

즉 자원이 여유로운 상황에서는 굳이 커넥션 풀 관리를 할 필요는 없을 것이니까 Client 구현체 설정을 안 해주면 Default를 사용하게 된다.

 

근데 Default 생성 부분에서는 커넥션 풀에 관한 설정이 없다.

 

즉 요청마다 3way-handshake 과정을 거치고 이후에 요청을 받는 것이다.

 

 

 

커넥션 풀을 사용는 것이 중요한 케이스

MSA 환경에서 다른 서버의 API 값을 불러오는 상황이라면 매 번 커넥션을 맺는 오버헤드는 분명 latency를 늘린다.

 

특히 중간 라우팅을 위한 서버일 뿐이라면 커넥션 풀을 안 쓰는 것은 분명 자원을 효율적으로 사용하지 못 하는 것이다.

 

 

커넥션 풀을 사용하지 않아도 상관이 없는 케이스

지연 시간에 영향을 받지 않고 도는 배치잡 같은 경우 커넥션 풀을 관리를 할 필요는 없어보인다.

10개씩 도는 배치잡을 위해 30개 가량의 커넥션 풀을 가지고 있는 것은 오히려 역으로 자원을 효율적으로 사용하지 못 하는 것이다. 

 

 

Feign Client에서 기본 클라이언트 대신 다른 클라이언트를 사용하는 방법

정말 간단하게 Bean으로 feign 모듈에 있는 Client 타입을 만들어서 등록 해주면 된다.

 

예를들어 Apache HttpClient를 사용한다고 하면 우선 해당 Client의 구현체를 갖는 모듈을 의존성에 추가해준다.

 

implementation 'io.github.openfeign:feign-httpclient'

 

그 다음에 해당타입의 Bean을 등록해주면 된다.

@Bean
fun client() : Client {
    return ApacheHttpClient(HttpClients.custom()
        .setMaxConnTotal(100).build())
}

 

추가적인 설정은 문서를 보고 각 환경에 맞게 진행하면 된다.

 

여기까지는 쉽다. 근데 이것만 보고서 사용하기에는 아쉽다. 그럼 어떻게 Client를 Bean으로 등록하면 등록한 걸로 사용이 될까?

 

디버깅을 해보면 Client 타입이 없는 경우 해당 Bean이 등록되는 구조인데 여기서 Client.Default를 보면 Default Client가 사용 되는 것을 확인 할 수 있고

 

Default Client의 실제 커넥션 사용 부분을 들어가다보면 해당 추상 클래스를 구현한 클래스를 사용하는 것을 볼 수 있다.

java.net.HttpURLConnection

 

 

커넥션을 가져오는 부분을 보면 사용 할 때마다 새롭게 커넥션을 생성하는 것을 볼 수 있다.

 

ApacheHttpClient를 Bean으로 등록하면 우선 Default Client가 등록이 안 되는 것을 확인 할 수 있었는데

이미 빈으로 등록된 클래스를 FeignClientFactoryBean 클래스에서

<T> T getTarget()

 

해당 메소드의 코드를 들어가보면

Client client = getOptional(feignClientFactory, Client.class);

 

다음과 같이 클라이언트를 가져오는 부분이 있는데

 

안에서 타입 기반으로 ApplicationContext에서 가져오는 부분을 확인 할 수 있다.

 

마무리

Feign Client는 너무 추상화가 잘 되어 있어서 간단한 설정 만으로 많은 것이 이루어진다.

하지만 너무 쉽게 되는 것은 문제 상황에 직면 했을 때 왜 안되지? 라는 의문을 제기 하는 것 이외에 할 수 있는 것이 없다.

그래서 커넥션 풀이 아무 설정 없으면 등록이 안 되는지, 클라이언트를 바꾸면 어떤 과정으로 바뀌게 되는지 확인 해 봤다.