项目用到了struts1+hibernate框架,使用的是c3p0连接池,容器用的resin4。
客户最近经常报障,保存缓慢,经常掉线要求重新登录。等等现象,最后的问题都是数据库有问题。开始我们优化sql语句,删数据,删除已经不合作的企业。能够解决一定问题。但是现在按照这么操作并不能继续解决问题了。然后开始分析错误原因。
报的错是
Could not open Hibernate Session for transaction;
查了一下,应该是c3p0连接池报的错,没法创建新的session,
偶尔还报出这样的错
com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory
查看了MySQL所在服务器,负载的确很高,已经到7-8左右了。
查看了MySQL的最大连接数。操作系统对MySQL用户最大创建进程数的限制。都没有什么问题。
把这些连接数调大了,升级了MySQL服务器的cpu核数。还是会报这样的问题。
然而在resin日志中,并没有报一些数据库问题。输出了查询时间,也都很正常。也就是说只要查询成功的语句,都很快。有很多对数据库的操作直接就失败了。
所以考虑了一下会不会是c3p0连接池有问题。在pom文件中查看c3p0的jar包已经是几乎十年前的版本了。抱着试一试的心态。更换了一下阿里druid连接池。除了换了applicationContext.xml里数据源的bean。其他的操作没有变。打了个包放到了线上。
线上业务程序有两个节点,连接同一个MySQL。两个节点通过阿里云的SLB进行负载均衡。
将刚才打包的程序上到了其中一个节点上。还会有客户陆续报障。但是根据客户提供的企业编号,查看到报障的企业操作日志都是在旧的节点产生的。也就是说新的节点目前没有问题。后来经过一下午的观察,陆陆续续有不到10家企业报障,都是在旧节点上。新节点没有问题。于是当天晚上在用户下班之后,运维同事升级了旧节点。第二天果然就没有用户报障了。同时myslq服务器的负载一整天都在0.5-1.5之间。比之前强很多。
总结这次数据库卡顿/失去连接,我们做出对应的解决方法有:
- 在用户报障的场景下看哪些sql语句有可以优化的点,通过explain查看,并且进行优化。
- 查看索引是不是有些需要加,有些需要删。
- 删除已经停用的企业。
- 删除历史业务数据。
- 增加数据库服务器性能。
- 更换连接池。