인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김용수님의 프로필 이미지
김용수

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

hikariCP mysql 접속 끊김 질문입니다

해결된 질문

작성

·

3.4K

3

안녕하세요 수강하면서 처음 질문 남깁니다.

h2데이터베이스 말고 mysql db를 이용하여 실습 해 보고 있는데요

아무것도 하지 않고 10분정도 지나면 connection이 종료되고 있습니다. 구글링 열심히 해봐도 도저히 답을 찾을 수 없어서

선생님께 질문 남겨 봅니다.

mysql 은 MS azure에 체험계정을 생성하여 원격으로 접속하고 있습니다.

당연히 방화벽은 다 열어주었고요

server os : ubuntu 20.0.4 LTS 

mysql 정보

버전 : 8.0

타임아웃 관련 mysql server 변수들

connect_timeout : 10

delayed_insert_timeout : 300

have_statement_timeout : YES

innodb_flush_log_at_timeout : 1

innodb_lock_wait_timeout : 50

innodb_rollback_on_timeout:OFF

interactive_timeout:28800

lock_wait_timeout:31536000

mysqlx_connect_timeout:30

mysqlx_idle_worker_thread_timeout:60

mysqlx_interactive_timeout:28800

mysqlx_port_open_timeout:0

mysqlx_read_timeout:30

mysqlx_wait_timeout:28800

mysqlx_write_timeout:60

net_read_timeout:30

net_write_timeout:600    <== 이 변수가 범인으로 의심 됩니다.

rpl_stop_slave_timeout:31536000

slave_net_timeout:60

wait_timeout:28800

아래는 어플리케이션을 실행하고 아무것도 하지 않고 10분이 지난 뒤 회원 조회를 하였을때 발생하는 에러입니다.

 Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:448)
(이하 생략)
hikariCp 설정 application.yml 입니다
spring:
datasource:
url: jdbc:mysql://{SERVER_IP}:3306/jpabook?serverTimezone=UTC&characterEncoding=UTF-8
username: {userId}
password: {userPassWord}
driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
pool-name: SpringBootJPAHikariCP
maximum-pool-size: 10
connection-timeout: 10000
validation-timeout: 10000

이렇게 상소를 올리니 비답을 내려주소서~~~

감사합니다^^

답변 3

3

김용수님의 프로필 이미지
김용수
질문자

상세하고 친절한 답변 감사합니다.

히카리 설정에서 max-lifetime을 580000(580초)로 설정하였더니 끊김현상은 사라졌습니다.

하지만 mysql서버에 sleep프로세스가 계속해서 생기는 문제가 발생하였는데요.

580초마다 hikariCP는 새로운 커넥션을 생성하면서 기존 커넥션들이 mysql서버에 살아있는 현상이 나타났습니다.

기존 커넥션들은 시간이 지나도 사라지지 않는데 아마  mysql 서버의 wait_timeout 변수값인 8시간이 지나야 사라질것으로 추측됩니다.

그래서 아래와 같이 application.yml에 connection-init-sql을 추가하여 세션의 wait_timeout을 강제로 10분 잡아주었더니 커넥션이 새로 만들어지고 기존의 커넥션들은 destroy되는 것을 확인했습니다.

    hikari:
pool-name: SpringBootJPAHikariCP
maximum-pool-size: 10
connection-timeout: 10000
validation-timeout: 10000
max-lifetime: 580000
connection-init-sql: set wait_timeout = 600

아무래도 개발 환경이다 보니 커넥션이 자주 발생하지 않아서 생긴 문제 같습니다.

선생님의 답변에서 힌트를 얻어서 해결하였네요. 

제 방법이 근본적인 해결방법이 아닌것 같아서 서버시스템쪽도 공부해야 할 것 같습니다.

이러다가 linux OS와 mysql 도 공부하게 생겼네요 ^^

언제나 힘이되어주는 답변 감사합니다.

요즘 아침기온이 쌀쌀한데 건강 유의하세요~

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 김용수님

이런 경우 대부분 이슈는 클라이언트 애플리케이션과 서버 사이에 데이터베이스 커넥션이 TCP/IP로 연결이 되었는데, 네트워크 중간에서 TCP 연결을 강제로 종료하고, TCP 종료 신호를 클라이언트에 주지 않은 경우에 발생합니다. 그러면 클라이언트는 연결이 되어 있다고 생각하는 것이지요. 주로 특정시간 이상 통신이 없으면 연결을 강제로 종료해서 문제가 발생합니다. 주로 방화벽이나 OS, 서버 어딘가에서 많이 발생하고 데이터베이스에서 발생할 수도 있습니다.

운영서버는 계속 서비스 요청이 있으니 이런 문제가 거의 없는데, 개발 서버 같은 경우 발생하기도 합니다.

그래서 히카리 풀에 유지되는 커넥션이 최대 10분 미만으로 유지되도록 설정하면 될 것 같아요. 그런데 진짜 10분에 끊어지는지도 테스트가 필요합니다. 사실은 5분에 끊어진건데, 10분뒤에 접속해서 문제가 발생한 것일 수도 있으니까요. 이 경우 5분 미만으로 잡으셔야 합니다. 그래서 max-lifetime을 해당 시간보다 더 적게 잡으면 해결 될 것 같습니다. 다음에 maxLifetime을 확인해주세요.

https://github.com/brettwooldridge/HikariCP

물론 이것과는 별도로 어디에서 10분에 끊어지는지는 많은 시간을 들여서 파보셔야 할 것 같아요.

감사합니다.

0

김영한님의 프로필 이미지
김영한
지식공유자

용수님 잘 해결하셨습니다^^

김용수님의 프로필 이미지
김용수

작성한 질문수

질문하기