admin write
blogblogblogbloglocation loglocation logtag listtag listguest bookguest book
rss feed

tomcat-jdbc로 MySQL에 연결한 경우 "java.net.SocketException: Broken pipe" 에러가 발생하는 경우를 가끔 볼 수 있다. 대부분의 경우 connection idle time이 MySQL에 설정된 wait_timeout을 지나서 DB에서 연결을 끊은 것이다. 이를 방지하려면 connection이 일정 기간동안 사용되지 않으면 close되도록 설정하거나 connection 대여시에 connection을 체크하도록 하면 된다.


설정 1 - 일정 기간동안 사용되지 않으면 connection을 테스트

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&amp;characterEncoding=utf8"

username="username" 

password="password" 

initialSize="10" 

minIdle="10"

maxIdle="50" 

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 wait_time 설정값 확인 방법 (단위: 초)

mysql>select @@global.wait_timeout;

+-----------------------+

| @@global.wait_timeout |

+-----------------------+

|                 28800         |

+-----------------------+

1 row in set (0.00 sec)



[출처] Tomcat7 tomcat-jdbc 설정 - Broken pipe 에러 회피|작성자 소프  

http://blog.naver.com/clotho95?Redirect=Log&logNo=140142861915






maxActive - 연결할 커넥션의 최대 갯수

maxIdle - 풀에 대기시킬 커넥션의 최대 갯수

minIdle - 풀에 대기시킬 커넥션의 최소 갯수 

  (0은 놀고있는 커넥션을 풀에 간직하지 않고 모두 close함을 뜻한다)


당연히 maxActive 값보다 maxIdle 값은 적어야 하며

maxIdle 보다 minIdle 값은 또 적어야 한다.


minIdle 을 0이상 잡을 경우

DB의 일방적인 세션 끊김을 방지하는 차원으로

testWhileIdle="true" 의 validation 속성을 추가로 설정하는것이 좋다.


ParameterDefaultDescription
validationQueryThe SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query MUST be an SQL SELECT statement that returns at least one row.