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

Idle in ALB, Connection Pool

by jay-choe 2024. 2. 7.

 

같은 용어이고 비슷한 개념이지만 실제 동작은 다르기 때문에 가끔 혼란스러운 경우가 있다.

 

그중에 'Idle Timeout'이 있다.

 

 

ALB Idle Timeout

보통 서비스는 앞에 부하 분산의 목적이나 무중단 배포를 위해 앞에 로드 벨런서를 둔다.

 

ALB는 HTTP/HTTPS 기반 즉 7계층으로 사용하는 로드벨런서기 때문에

헤더 추가라던지 헤더 내부에서 정의하는 호스트 기반 라우팅이라던지 편리한 기능이 많다.

 

보통 앞에 ALB를 붙이면 이런 식으로 구성되게 되는데

Idle Timeout은 Client에서 ALB로 요청을 할 때 저 연결 흐름에서

 

해당 시간 동안 주고 받는 데이터가 없으면 커넥션이 제거된다.

 

즉 클라이언트 요청 시점에서 요청 처리에 idle timeout 시간이 초과 되면

 

해당 커넥션은 제거 되며 504 timeout 상태코드를 받게 된다.

 

 

음 그럼 idle timeout은 처리 시간이 오래 걸려서 발생하는 것이고

(처리 시간 동안은 주고 받는 데이터가 없으니)

 

ALB쪽 idle timeout은 처리 시간에 제한을 두는 것이라고 생각 할 수 있겠다.

 

 

Connection Pool (HikariCP)

먼저 Spring Boot를 쓰면 기본적인 DB 커넥션 풀은 HikariCP를 쓰므로 해당 커넥션 풀 기준으로 확인하였다.

 

connection pool 설정 값 중에 마찬가지로 idle timeout이 존재한다.

 

 

Github 레포에서 설명 된 내용 중 필요한 내용을 정리하면 idle 상태에 있을 수 있는 커넥션의 시간을 설정하는 것이다.

 

idle 상태는 해석 그대로 게으른 상태 

즉 아무 것 도 안하는 상태인데

 

모호하다. 뭐가 아무 것도 안 하는건지.

 

예를들어 idleTimeout이 60초인데 DB에서 쿼리 후 데이터를 가져오는데 62초가 걸린다면
이 시간동안 connection은 아무 것 도 안 하는 것일까?

 

pool에서 가만히 아무 것도 안 하는 거라면..

 

pool에서 꺼냈을 때 아무 것 도 안 하는 시간은 고려되지 않는 것일까?

 

물론 HikariCP는 커넥션 풀 라이브러리고 관점은 이에 맞게 '커넥션 풀' 이 되어야 하는 것이 맞다고 생각한다.

 

하지만 ALB idle timeout과 동일한 단어로 인해서 혼동이 된다.

 

그래서 궁금증을 풀고자 코드를 뜯어봤다. (어차피 동작은 코드가 하니까)

 

HikariCP는 코드가 재밌다.

 

Connection을 모은 클래스를 Bag이라고 표현하고

 

Connection을 가져 오는 것을 빌린다(borrow)고 표현하다.

 

 

우선 자바독에 써있는 것을 확인하다 보면

 

PoolEntry 라는 클래스가 있고 이 클래스는 커넥션 객체를 트래킹 하기 위한 클래스라고 한다.

이 안에는 state라는 필드가 있다.

 

해당 커넥션의 상태를 나타내는 값을 담는 변수로 확인 할 수 있다.

 

근데 int 값이고 magic number를 쓰는 것 같은데 이 상태들에는 뭐가 있는지 코드를 따라가다 보면

 

 

여기서 정의한 상태 값들을 사용하는 것을 볼 수 있다.

 

사용 할 때는 STATE_IN_USE

다 쓰고 나면 STATE_NOT_IN_USE로 쓰는 것을 확인 해 볼 수 있다.

 

 

실제 connection을 가져오는 부분인데

 

처음에는 ThreadLocal 즉 사용하는 쓰레드에 있는지 먼저 체크하고 없으면 원래 풀에서 다시 가져오는 방식으로 보인다.

 

여기서 중심적으로 볼 부분은 compareAndSet이다.

 

CAS 라고 불리는 이 친구 원자적 연산으로 사용할 때 쓰인다.

(비교 + 대입) -> 이 과정이 1 번의 연산이라는 뜻이다. 공유자원이기 때문에 원자적 연산으로 보호해주려는 목적이다.

 

그래서 저 compareAndSet 메서드를 보면 STATE_NOT_IN_USESTATE_IN_USE로 바꾸고 가져오고 있다.

 

즉 커넥션을 가져오는 시점에 해당 커넥션을 사용중으로 상태로 바꾼다.

 

 

커넥션을 사용하고 다시 pool에 돌려놓는 부분은 재활용(recycle)한다고 표현하였는데

 

여기서 requite(갚는다)로 가보면 바로 STATE_NOT_IN_USE로 바꿔주는 것을 볼 수 있다.

 

 

위 코드들을 통해서 커넥션은 상태를 갖고 사용중, 사용중이지 않음 등의 상태로 나타난다는 것을 확인했다.

 

그럼 Idle 이라는 것은 코드 상으로 어떻게 정의하는 것일까?

 

HikariCP에서 IdleConnection은 NOT_IN_USE 상태라는 것을 다음 코드를 통해서 명확히 확인 할 수 있다.

 

즉 Idle 상태에 대한 정의는 코드를 통해서 확인 했 듯 사용중이지 않은 상태이고 이 상태는 connection을 다 쓰고 반납 한 상태 혹은 아예 처음 상태(생성만 함)를 나타낸다.

 

 

Idle Connection 시간이 지난 커넥션은 HouseKeeper라는 클래스가 처리하는데

위의 코드를 보면 사용중이지 않은 상태의 커넥션중 idle timeout 시간이 지난 커넥션을 제거한다.

 

물론 최소한의 쓰레드 갯수 설정 값을 넘은 케이스만 진행한다.

 

 

결론적으로 Connection Pool에서 idle은 Pool에서 대기하고 있는 시간 으로 정의 하는 것이며, DB 요청에 걸리는 시간과는 아무 상관이 없다.

'허브 살리기 프로젝트' 카테고리의 다른 글

CPU Pinning  (0) 2024.02.14
Connection Timeout Monitoring in Connection Pool  (1) 2024.02.11
TCP, HTTP/HTTPS keep-alive  (1) 2024.02.05
Gradle Java plugin API and Implementation  (0) 2024.01.31
SSD Sequantial Read/Write  (1) 2024.01.30