出现Tomcat假死状态



使用了阿里的durid这个数据连接池技术,可是把这套程序一部署上服务器运行15个小时就会出现Tomcat假死状态,Tomcat日志,里面出现了com.alibaba.druid.pool.GetConnectionTimeoutException: loopWaitCount 0, wait millis 15000这个错误信息,我就把最大链接数改大了,现在能支撑2天不宕,过了两天又出现这个问题,这个问题能根解吗,设置最大连接数只是个治表的办法。
我将我们的配置以及一些源码发出来,求大神们帮忙看看,到底是哪里没关闭链接。数据库连接池产生的连接不都是由连接池来维护这个连接的生命周期吗,为什么还会出现这样连接不会自动关闭,是durid本身的BUG吗?

import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DBConnection
{
  public static DruidDataSource ds;
  
  static
  {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-datasource.xml");
    ds = (DruidDataSource)context.getBean("dataSource");
  }
  
  public static Connection getConnection()
    throws SQLException
  {
    return ds.getConnection();
  }
}
import com.whszzy.Utils.WSUtil;
import com.whszzy.cache.CacheManager;
import java.io.Serializable;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

public class DBHelper
{
  private Connection dbConnection = null;
  
  public DBHelper()
  {
    try
    {
      this.dbConnection = DBConnection.getConnection();
    }
    catch (SQLException e)
    {
      WSUtil.error(e);
    }
  }
  
  public Connection getConnection()
  {
    return this.dbConnection;
  }
  
  public List<Map<String, Object>> query(String sql)
  {
    long dt1 = System.currentTimeMillis();
    try
    {
      return (List)new QueryRunner().query(this.dbConnection, sql, new MapListHandler());
    }
    catch (SQLException ex)
    {
      ex.printStackTrace();
    }
    return null;
  }
  
  private static final ScalarHandler _g_scaleHandler = new ScalarHandler()
  {
    public Object handle(ResultSet rs)
      throws SQLException
    {
      Object obj = super.handle(rs);
      if ((obj instanceof BigInteger)) {
        return Long.valueOf(((BigInteger)obj).longValue());
      }
      return obj;
    }
  };
}

——解决思路———————-
感觉可能你的程序有问题把,是不是有程序占着数据库连接不释放呀?
把线程堆栈dump出来看看,有没有死锁的线程。数据库也可以看看是什么sql占着连接不释放。
——解决思路———————-
connection 用完了要记得调用close()方法 . 否则很快连接池里就没有可用的连接了. 你看下durid , 它有个配置可以关闭长时间不用的连接.


https://github.com/alibaba/druid/wiki/%E8%BF%9E%E6%8E%A5%E6%B3%84%E6%BC%8F%E7%9B%91%E6%B5%8B

<bean id=”dataSource” class=”com.alibaba.druid.pool.DruidDataSource” destroy-method=”close”>
… …
<property name=”removeAbandoned” value=”true” /> <!– 打开removeAbandoned功能 –>
<property name=”removeAbandonedTimeout” value=”1800″ /> <!– 1800秒,也就是30分钟 , 关闭30分钟内没有使用的连接 –>
<property name=”logAbandoned” value=”true” /> <!– 关闭abanded连接时输出错误日志 –>