JDBC Flow
JDBC는 데이터 접근의 편의성과 일괄성 제공을 위한 DataAccess와 DB 연결과 상호 작용을 위한 JDBC API로 구성이 되어있습니다.
DataAccess
- DataAccess 계층은 Repository 또는 DAO 패턴의 구현체를 의미하며, Persistence Framework 또는 Query Object 등의 구성 요소를 통해서 JDBC 구현 계층인 dataSource와 상호 작용합니다.
- CRUD는 Application이 DB 데이터를 직접 다루는 방식을 말하며 Persistence Framework는 Framework를 이용하여 직간접적으로 DB 데이터를 다루는 방식을 의미합니다.
- Persistence Framework
- Persistence Framework는 SQL문으로 직접 DB 데이터를 다루는 SQL Mapper와 Java 객체를 통해 간접적으로 DB 데이터를 다루는 ORM(Object-Relational Mapper)으로 구분합니다.
- MyBatis는 SQL Mapper의 대표적인 구현체이며 Hibernate는 JPA(ORM)의 구현체중 하나입니다.
JDBC 구현 계층
- JDBC 구현 계층은 DB 연결 및 상호작용을 위해 JDBC Driver와 DataSource로 구분할 수 있습니다.
- JDBC Driver는 DBMS 벤더에서 정의한 네트워크 프로토콜을 사용하여 DB와 통신하는 역할을 담당합니다. 이러한 이유로 JDBC Driver의 구현체는 각 DBMS 벤더에서 제공됩니다.
- DataSource는 JDBC Driver를 통해서 맺어진 DB와의 연결을 관리하는 역할을 담당합니다. DataSource는 DriverManager에서 발전된 형태로써 더 편리한 DB 연결과 커넥션 풀을 활용한 효율적인 DB 연결 관리 기능을 제공합니다. DataSource의 구현체는 각 DBMS 벤더 또는 OSS/서드파티를 통해서 제공됩니다.
Timeout 이해하기
JDBC Driver는 네트워크 프로토콜을 사용하여 DB와 통신합니다. 이는 일반적으로 TCP/IP 연결을 의미하고, JDBC Driver가 TCP 소켓(이하 소켓)을 사용하여 DB와 통신하도록 구현된다는 것을 의미합니다. 따라서 소켓 통신에서 발생하는 Timeout은 JDBC Driver에서도 동일하게 발생합니다.
JDBC에서 발생할 수 있는 Timeout는 Connection Timeout, Socket Timeout이 있으며 TCP/IP에서 발생하는 내용과 같다고 생각하시면 되겠습니다.
StatementTimeout
StatementTimeout은 하나의 요청 처리 시간을 나타냅니다.
- Connection.createStatement() 메서드를 호출하여 Statement를 생성한다.
- Statement.executeQuery() 메서드를 호출한다.
- Statement는 내부 Connection을 사용하여 MySQL DBMS로 쿼리를 전송한다.
- Statement는 타임아웃 처리를 위해 새로운 타임아웃 처리용 스레드를 생성한다. 5.1.x 버전에서는 Connection에 한 개의 스레드가 할당되는 것으로 변경되었다.
- 스레드에 타임아웃 처리를 등록한다.
- 타임아웃이 발생한다.
- 타임아웃 처리 스레드가 Statement와 동일한 설정의 Connection을 생성한다.
- 생성된 Connection을 사용하여 취소 쿼리(KILL QUERY "connectionId")를 전송한다.
TransactionTimeout, Socket Timeout
TransactionTimeout은 StatementTimeout x N을 의미합니다. 물론 StatementTimeout 이외 GC 및 기타 소요 시간도 포함될 수 있습니다.
socketTimeout
JDBC 드라이버의 SocketTimeout 값은 DBMS가 비정상으로 종료되었거나 네트워크 장애(기기 장애 등)가 발생했을 때 필요한 갑입니다.
TCP/IP의 구조상 소켓에는 네트워크의 장애를 감지할 수 있는 방법이 없습니다. 그렇기 때문에 애플리케이션은 DBMS와의 연결 끊김을 알 수 없습니다. 이럴 때 SocketTimeout이 설정되어 있지 않다면 애플리케이션은 DBMS로부터의 결과를 무한정 기다릴 수도 있습니다(Dead Connection).
이러한 상태를 방지하기 위해 소켓에 타임아웃을 설정해야 합니다. SocketTimeout은 JDBC 드라이버에서 설정할 수 있습니다. SocketTimeout을 설정하면 네트워크 장애 발생 시 무한 대기 상황을 방지하여 장애 시간을 단축할 수 있습니다.
단, SocketTimeout 값을 Statement의 수행 시간 제한을 위해 사용하는 것은 바람직하지 않습니다. 그러므로 SocketTimeout 값은 StatementTimeout 값보다는 크게 설정해야 합니다. SocketTimeout값이 StatementTimeout보다 작으면, SocketTimeout이 먼저 동작하므로 StatementTimeout 값은 의미가 없게 되어 동작하지 않습니다.
Socket Timeout의 목적은 호스트와 맺어진 물리적인 연결에서 네트워크 장애가 발생하였을 경우 이를 애플리케이션에서 감지하여 장애에 대한 예외 처리를 수행할 수 있도록 하는 것입니다. 반면 Statement Timeout의 용도는 DB에서 수행되는 SQL 문(Statement) 한 개의 수행 시간을 제한하는 것입니다.
Connection Timeout, Read Timeout 값을 설정할 때 dataSourceClassName 옵션을 설정한 경우에는 dataSourceProperties를 이용해서 값을 지정해야 하고, jdbcUrl 옵션을 설정한 경우는 URL 형식에 맞춰서 값을 지정해 줘야 합니다. 대표적인 JDBC Driver 구현체들에서 Connection Timeout, Read Timeout 옵션을 적용하기 위한 속성들은 다음과 같습니다.
JDBC Driver VendorConnection TimeoutRead Timeout
MySQL Connector/J | connectionTimeout | socketTimeout |
JDBC Driver for SQL Server | loginTimeout | socketTimeout |
PostgreSQL JDBC Driver | connectTimeout | socketTimeout |
Oracle JDBC Driver | oracle.net.CONNECT_TIMEOUT | oracle.jdbc.ReadTimeout |
참고
https://netmarble.engineering/hikaricp-options-optimization-for-game-server/
https://netmarble.engineering/jdbc-timeout-for-game-server/
https://d2.naver.com/helloworld/1321
https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-networking.html#cj-conn-prop_socketTimeout
https://wiki.daumkakao.com/pages/viewpage.action?pageId=721323570
https://tomining.tistory.com/164
'DEVELOPE > DevOps' 카테고리의 다른 글
Jenkins Manster, Slave on kubernetes (0) | 2023.02.14 |
---|---|
kubernetes 동작 (0) | 2021.06.20 |
댓글