-
[HikariCP] idleTimeout 알아보기Java 2024. 7. 18. 06:08반응형
- 목차
idleTimeout 이란 ?
HikariPool DataSource 는 maximumPoolSize 를 통해서 최대 Connection 의 갯수를 지정할 수 있습니다.
만약에 maximumPoolSize 를 6개로 설정한다면 아래의 이미지처럼 하나의 Connection Pool 은 최대 6개의 Connection 을 보유합니다.
Connection Pool 이 데이터베이스와 맺는 이 Connection 은 사실상 TCP Network Connection 이며, 아래의 출력 결과와 같이 TCP Socket 이 생성되게 됩니다.
( lsof 명령어나 MySQL 의 show processlist; 명령어 등을 통해서 현재 생성된 TCP Socket 을 확인할 수 있습니다. )
lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 736 root 9u IPv6 80835 0t0 TCP fbbbd46ffc0b:44556->mysql.mysql:mysql (ESTABLISHED) java 736 root 12u IPv6 80838 0t0 TCP fbbbd46ffc0b:44572->mysql.mysql:mysql (ESTABLISHED) java 736 root 13u IPv6 81657 0t0 TCP fbbbd46ffc0b:44580->mysql.mysql:mysql (ESTABLISHED) java 736 root 14u IPv6 87099 0t0 TCP fbbbd46ffc0b:44588->mysql.mysql:mysql (ESTABLISHED) java 736 root 16u IPv6 85303 0t0 TCP fbbbd46ffc0b:44596->mysql.mysql:mysql (ESTABLISHED)
show processlist; +----+-----------------+------------------+-------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+-------+---------+------+------------------------+------------------+ | 5 | event_scheduler | localhost | NULL | Daemon | 8533 | Waiting on empty queue | NULL | | 68 | root | localhost | NULL | Query | 0 | init | show processlist | | 69 | root | 172.18.0.3:48106 | mysql | Sleep | 1 | | NULL | | 70 | root | 172.18.0.3:48112 | mysql | Sleep | 1 | | NULL | | 71 | root | 172.18.0.3:48120 | mysql | Sleep | 1 | | NULL | | 72 | root | 172.18.0.3:48130 | mysql | Sleep | 1 | | NULL | | 73 | root | 172.18.0.3:48138 | mysql | Sleep | 1 | | NULL | +----+-----------------+------------------+-------+---------+------+------------------------+------------------+ 7 rows in set (0.00 sec)
이때에 어떠한 TCP Packet 도 전송되지 않는 Idle 상태의 Connection 은 사실상 시스템에 있어서 자원낭비에 해당합니다.
OS 커널 입장에서도 Socket 을 관리해야하고, 이러한 소켓을 위한 별도의 메모리 공간도 필요하며,
하나의 Process 가 가질 수 있는 FD 갯수도 제한적이기 때문에 Idle Connection 은 리소스가 낭비되는 상황이 됩니다.
따라서 HikariPool 은 이러한 Idle Connection 에 Idle Timeout 을 적용하여 특정 시간동안 어떠한 TCP Packet 이 전송되지 않는 Connection 은 제거하게 됩니다.
IdleTimeout 을 직접 적용해보기.
아래의 코드는 IdleTimeout 은 10초로 설정하고, 2개의 Min Connection 과 5개의 Max Connection 을 가지는 Pool 을 생성합니다.
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.SQLException; public class HikariPoolMonitor { public static void main(String[] args) throws InterruptedException { // HikariCP 설정 HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://mysql:3306/mysql"); config.setUsername("root"); config.setPassword("1234"); config.setMinimumIdle(2); config.setMaximumPoolSize(5); config.setIdleTimeout(10000); // Hikari DataSource 생성 HikariDataSource dataSource = new HikariDataSource(config); try { Connection c1 = dataSource.getConnection(); Connection c2 = dataSource.getConnection(); Connection c3 = dataSource.getConnection(); Connection c4 = dataSource.getConnection(); Connection c5 = dataSource.getConnection(); c1.close(); c2.close(); c3.close(); c4.close(); c5.close(); } catch (SQLException e) {} // 5초 단위로 HikariCP 풀 상태를 출력하는 루프 while (true) { printHikariPoolStatus(dataSource); Thread.sleep(5000); // 5초 대기 } // 데이터소스 종료 // dataSource.close(); } // HikariCP 풀 상태 출력 함수 private static void printHikariPoolStatus(HikariDataSource ds) { System.out.println("========== HikariCP Pool 상태 =========="); System.out.println("총 커넥션 수: " + ds.getHikariPoolMXBean().getTotalConnections()); System.out.println("활성 커넥션 수: " + ds.getHikariPoolMXBean().getActiveConnections()); System.out.println("유휴 커넥션 수: " + ds.getHikariPoolMXBean().getIdleConnections()); System.out.println("대기 중인 스레드 수: " + ds.getHikariPoolMXBean().getThreadsAwaitingConnection()); System.out.println("====================================\n"); } }
위 코드가 실행되면 아래와 같은 출력을 뱉습니다.
idleTimeout 인 10초가 지나게 되면 최대 5개에서 2개의 Connection 으로 Connection Pool 의 사이즈가 줄어듦을 확인할 수 있습니다.
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting... [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@45c7e403 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed. ========== HikariCP Pool 상태 ========== 총 커넥션 수: 5 활성 커넥션 수: 0 유휴 커넥션 수: 5 대기 중인 스레드 수: 0 ==================================== ========== HikariCP Pool 상태 ========== 총 커넥션 수: 2 활성 커넥션 수: 0 유휴 커넥션 수: 2 대기 중인 스레드 수: 0 ====================================
TCP 관점에서 살펴보기.
tcpdump 명령어를 통해서 Idle Connection 의 TCP Packet 전달 과정을 확인합니다.
Idle Connection 은 정말 어떠한 TCP Packet 도 보내지 않습니다.
그래서 TCP Packet 을 포착하지 못하였구요.
대신 아래의 TCP Packet 들은 Connection 의 종료를 알리는 4 way handshake 단계의 Packet 들입니다.
Flag 가 F 또는 R 인 Packet 들이 보이며, 이것은 Finish 와 Reset 을 의미합니다.
그리고 이러한 Flag 의 Packet 은 Connection 의 종료를 의미합니다.
13:53:16.937562 IP mysql.3306 > zealous_pascal.mysql.45256: Flags [F.], seq 4112, ack 2044, win 524, options [nop,nop,TS val 131635901 ecr 2691528606], length 0 0x0000: 4500 0034 3847 4000 4006 aa53 ac12 0002 E..48G@.@..S.... 0x0010: ac12 0003 0cea b0c8 4610 34de e072 c36c ........F.4..r.l 0x0020: 8011 020c 5850 0000 0101 080a 07d8 9abd ....XP.......... 0x0030: a06d 779e .mw. 13:53:16.938476 IP mysql.3306 > zealous_pascal.mysql.45256: Flags [R], seq 1175467231, win 0, length 0 0x0000: 4500 0028 0000 4000 4006 e2a6 ac12 0002 E..(..@.@....... 0x0010: ac12 0003 0cea b0c8 4610 34df 0000 0000 ........F.4..... 0x0020: 5004 0000 1f15 0000 P....... 13:53:16.944338 IP mysql.3306 > zealous_pascal.mysql.45254: Flags [F.], seq 4112, ack 2124, win 524, options [nop,nop,TS val 131635908 ecr 2691528613], length 0 0x0000: 4500 0034 1082 4000 4006 d218 ac12 0002 E..4..@.@....... 0x0010: ac12 0003 0cea b0c6 7253 385e 8f02 ebbb ........rS8^.... 0x0020: 8011 020c 5850 0000 0101 080a 07d8 9ac4 ....XP.......... 0x0030: a06d 77a5 .mw. 13:53:16.944406 IP mysql.3306 > zealous_pascal.mysql.45254: Flags [.], ack 2125, win 524, options [nop,nop,TS val 131635908 ecr 2691528613], length 0 0x0000: 4500 0034 1083 4000 4006 d217 ac12 0002 E..4..@.@....... 0x0010: ac12 0003 0cea b0c6 7253 385f 8f02 ebbc ........rS8_.... 0x0020: 8010 020c 5850 0000 0101 080a 07d8 9ac4 ....XP.......... 0x0030: a06d 77a5 .mw. 13:53:16.947459 IP mysql.3306 > zealous_pascal.mysql.45238: Flags [F.], seq 4112, ack 2124, win 524, options [nop,nop,TS val 131635911 ecr 2691528616], length 0 0x0000: 4500 0034 c192 4000 4006 2108 ac12 0002 E..4..@.@.!..... 0x0010: ac12 0003 0cea b0b6 596a b8c0 246c 6e76 ........Yj..$lnv 0x0020: 8011 020c 5850 0000 0101 080a 07d8 9ac7 ....XP.......... 0x0030: a06d 77a8 .mw. 13:53:16.947494 IP mysql.3306 > zealous_pascal.mysql.45238: Flags [.], ack 2125, win 524, options [nop,nop,TS val 131635911 ecr 2691528616], length 0 0x0000: 4500 0034 c193 4000 4006 2107 ac12 0002 E..4..@.@.!..... 0x0010: ac12 0003 0cea b0b6 596a b8c1 246c 6e77 ........Yj..$lnw 0x0020: 8010 020c 5850 0000 0101 080a 07d8 9ac7 ....XP.......... 0x0030: a06d 77a8 .mw.
관련 명령어들.
docker network create mysql docker run -d --platform linux/amd64 --network mysql --name mysql --hostname mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:8.0.23 docker run -it --network mysql --rm -v /tmp/HikariPoolMonitor.java:/tmp/HikariPoolMonitor.java openjdk:11 /bin/bash cd /tmp/ wget https://repo1.maven.org/maven2/com/zaxxer/HikariCP/5.1.0/HikariCP-5.1.0.jar wget https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar wget https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.36/slf4j-simple-1.7.36.jar wget https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar -P /tmp javac -cp HikariCP-5.1.0.jar:slf4j-api-1.7.36.jar:slf4j-simple-1.7.36.jar:mysql-connector-j-8.0.33.jar HikariPoolMonitor.java java -cp .:HikariCP-5.1.0.jar:slf4j-api-1.7.36.jar:slf4j-simple-1.7.36.jar:mysql-connector-j-8.0.33.jar HikariPoolMonitor
반응형'Java' 카테고리의 다른 글
[HikariCP] keepaliveTime 와 관련된 여러가지 실험 (0) 2024.07.22 [HikariCP] connectionTimeout 설정 알아보기 (0) 2024.07.11 [Java Serialization] 여러가지 자바 직렬화 해석 방식들 (0) 2024.07.06 Java ReentrantLock 알아보기 (0) 2024.06.03 [Java] 익명 클래스와 메모리 관계 알아보기 ( Anonymous Class , Method Area ) (0) 2024.06.02