4,562,968 th visitor since 2017.2.1 ( Today : 419 )
Programming
No. 694
Name. swindler
Subject. Tomcat Connection Pool Connection유지
Main Cate. JSP/Servlet
Sub Cate. MySQL
Date. 2013-01-11 18:21
Hit. 7641 (211.36.27.3)
File.
tomcat-jdbc로 MySQL에 연결한 경우 "java.net.SocketException: Broken pipe" 에러가 발생하는 경우를 가끔 볼 수 있다.

connection을 max_timewait 보다 오랜기간 동안 사용하지 않은 경우
mysql db 쪽에서 접속을 끊어서 발생하는 경우이다.
일반적으로 사용자가 어느정도 있는 사이트에서는 발생하지 않는다.
close되도록 설정하거나 connection 대여시에 connection을 체크하도록 하면 된다.

1 - 일정 기간동안 사용되지 않으면 query 실행
validationQuery="SELECT 1"
testWhileIdle="true"
minEvictableIdleTimeMillis="3600000"
timeBetweenEvictionRunsMillis="60000"

(*) DB에 쿼리를 하기 때문에 이 때마다 DB의 session idle time이 갱신된다. 만약 connection이 이미 끊겼다면 에러가 발생할테고 해당 connection은 pool에서 제거된다.

(*) timeBetweenEvictionRunsMillis의 기본값은 5000 (5초)이고, minEvictableIdleTimeMillis의 기본값은 60000 (60초)이다. minEvictableIdleTimeMillis 값은 MySQL에 설정된 wait_timeout이나 방화벽에 설정된 session timeout 값보다 작아야 한다.

설정 2 - connection 대여 시 테스트
validationQuery="SELECT 1"
testOnBorrow="true"

(*) 매번 connection 대여 시 마다 체크하는 것은 아니다. 체크 한 connection은 validationInterval 기간 안에는 다시 체크하지 않는다. validationInterval의 기본값은 30000 (30초).

설정 3 - 일정 기간동안 사용되지 않으면 connection을 close
minIdle="0"

설정 1을 사용한 JDBC Resource 설정 예
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/testDB" auth="Container" type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/smartconnect?useUnicode=true&characterEncoding=utf8"
username="xxxx"
password="yyyy"
initialSize="5"
minIdle="5"
maxIdle="20"
maxActive="50"
maxWait="5000"
validationQuery="SELECT 1"
validationInterval="30000"
testWhileIdle="true" />
</Context>

tomcat-jdbc PoolCleaner 동작
PoolCleaner thread는 timeBetweenEvictionRunsMillis 만큼 sleep하다 idle/abandoned connection을 체크한다.
removeAbandoned="true"이면 abandoned connection 체크
connection이 대여된 후 removeAbandonedTimeout (초, 기본값 60)안에 반납되지 않으면 connection을 pool에서 제거하고 close한다.
pool의 idle connection 개수가 minIdle보다 크면 체크
idle connection 개수가 minIdle이 될 때 까지 마지막 사용시간이 minEvictableIdleTimeMillis (기본값 60000)을 지난 idle connection을 찾아 pool에서 제거하고 close한다.
testWhileIdle="true"이면 idle connection들에 대해 validation 테스트
전체 idle connection에 대해 validationQuery에 설정된 SQL을 수행해서 Exception이 발생하면 pool에서 제거하고 close한다.

MySQL 설정값 확인 방법 (단위: 초)

show variables where Variable_name = 'wait_timeout'
show global variables where Variable_name='wait_timeout';

[바로가기 링크] : http://coolx.net/cboard/develop/694



Name
Password
Comment
Copyright © 1999-2017, swindler. All rights reserved. 367,611 visitor ( 1999.1.8-2004.5.26 ), 2,405,771 ( -2017.01.31)

  2HLAB   2HLAB_Blog   RedToolBox   Omil   Omil_Blog