c3p0连接池拿不到连接导致系统崩溃的问题解决

问题描述

在一个很突然的时刻,某一台应用服务器挂掉了。该台服务器承载的是一个单体应用,并发量也很小,下面开始排查…

查看服务器进程

①通常在linux服务器上我们查看进程使用的是ps -ef | grep tomcat(使用tomcat作为应用服务器)
②同样也可以使用 jps -l 命令查看当期正在运行的java进程org.apache.catalina.startup.Bootstrap就是我们的tomcat进程啦

tomcat输出日志查看

我们看到进程是正常的,接下来查看日志输出情况
进入到tomcat/logs目录下
输入命令 tail -f catalina.out查看当前是否有日志输出

java.io.IOException:打开的文件过多
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:54)
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:54)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:551)
at java.lang.Runtime.exec(Runtime.java:477)
at java.lang.Runtime.exec(Runtime.java:443)

查看当前打开文件大小

lsof -p 直接查看打开的文件
lsof -p | wc -l 查看打开文件的数量 (65560)

然后我们可以查看一下当前服务器支持的最大文件打开数量:
ulimit -a
在这里插入图片描述
这里好像已经没有设置最大打开文件数量的空间了

日志分析

我们将服务器的运行日志拷贝到本地,截取服务器挂掉的那个时间段,进行一波日志查看
在这里插入图片描述
这里显示这个web应用的实例已经停止,为了调试以及试图终止导致非法访问的线程,将引发以下堆栈跟踪。
通过C3P0PooledConnectionPoolManager[identityToken->10q1nwma11dqw4ut1ya84pd|3384a844, dataSourceName->oracle]-HelperThread-#2这条信息,假象是c3p0连接池出了问题,拿不到连接导致应用停止。

查看c3p0配置信息

在这里插入图片描述
到这里仍然没有问题,那会不会是工具类的问题呢?

jdbcutils工具类查看

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

public class JdbcUtils {
    private static  Properties properties = null;
       
    public static Connection getOConnection() {
        //通过标识名来创建相应连接池
        ComboPooledDataSource dataSource = new ComboPooledDataSource("oracle");
        /*Connection con = dataSource.getConnection();

        return  con;*/
        try {
            return dataSource.getConnection();

        } catch (Exception e) {
           // logger.error("Exception in C3p0Utils!", e);
            throw new RuntimeException("数据库连接出错!", e);
        }
    }

    //释放连接回连接池
    public static void close(Connection conn, PreparedStatement pst, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                //logger.error("Exception in C3p0Utils!", e);
                throw new RuntimeException("数据库连接关闭出错!", e);
            }
        }
        if(pst!=null){
            try {
                pst.close();
            } catch (SQLException e) {
                //logger.error("Exception in C3p0Utils!", e);
                throw new RuntimeException("数据库连接关闭出错!", e);
            }
        }

        if(conn!=null && conn.isClosed()){
            try {
                conn.close();
            } catch (SQLException e) {
               // logger.error("Exception in C3p0Utils!", e);
                throw new RuntimeException("数据库连接关闭出错!", e);
            }
        }
    }
}

到这里问题应该是一目了然了。。。
由于每次从c3p0连接池获取连接的时候都会初始化一个dataSource来占用连接池中的一条连接,并且在调用conn.close()之后,只会释放,并不会关闭,所以理论上在调用几次之后,连接池应该已经干涸了。。。

我们将这段代码放到全局中,只要一加载工具类,就初始化一个dataSource就好了
ComboPooledDataSource dataSource = new ComboPooledDataSource(“oracle”);

总结

这个时候一定要会甩锅。。。这个代码不是我写的!!!
然后下次一定不能犯这么蠢的问题。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值