[펌]Tomcat7 tomcat-jdbc 설정 – Broken pipe 에러 회피

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 에러 회피|

 

 

[[추가]]

jdbc connection string에 하기와 같이 autoconnection option을 추가 해줘도 된다.

즉 이 옵션이 켜 있으면 끊긴 커넥션을 자동으로 재 접속 처리 한다.

문제는.. 트랜잭션이 걸려 있을 경우 잘 못 하면 트랜잭션이 꼬일 수 있으므로

복잡한 작업을 하는 경우에는 이 옵션을 꺼 놓는게 좋다..

 

잘 못된 데이서 생성 보다는 오류 메시지 표출이 나으니깐..

Cannot get a connection, pool error Timeout waiting for idle object (Tomcat forum at JavaRanch)

첨언:: 각 옵션을 복합적으로 사용할때는 &를 써야 하는데 이게 오류를 일으킨다. 그래서

&amp; 로 바꿔서 각 옵셕을 이어주면 된다.

?characterEncoding=UTF-8&amp;autoConnect=true