【影响范围】
全网不可用
【故障表现】
页面报内部服务错误
【处理过程】
1、9点40,业务团队后端服务监控群、大数据后端服务监控群等,出现大量报警,提示“1040】Too many connections”
2、查看各数据库服务器的数据库连接情况,发现10.0数据库服务器,数据库连接数已达到上限
3、查看当前服务器MySQL在运行的线程,发现大数据库账号的线程数达到919个
4、检查大数据可能导致异常的服务,发现只有服务A初始化数据会导致。停止该服务后,连接数恢复正常。
【原因分析】
1、主要原因
大数据初始化服务A,因只关闭数据库连接,没有关闭数据库连接池,且没有限制连接池数量,导致数据连接持续增加,最后达到最大值2k,因数据库连接达到上线而导致请求不来。
2、次要原因
数据库连接缺少监控,导致业务报警后,迟迟定位不到原因
大数据读的主库,扩大了影响范围,提升了故障等级
【其他】
业务报警8点40发生,用户9点36反馈,我们有56分钟的时间可以在用户无感知的情况下解决这个问题,但我们没有解决,质量管理部需要牵头规范解决这个问题,提升我们解决故障的效率。
【改进措施]
1、修复对应Bug
2、增加数据库连接数监控
3、10.0增加从库,大数据通过从库读业务库
4、确保资源层面监控无遗漏(服务器、数据库、中间件、网络一级运维角度看到的应用是否健康等)
5、梳理系统内可能存在的风险,并制相应制度和规范来消除风险
这几天给项目做性能压力测试,发现一个方法压力200之后就会把整个系统弄停掉。仔细检查发现是开发人员调用
数据库
的写法有问题。用的是spring的jdbcTemplate,在
使用
回调的
时
候,在回调里又做了
数据库
的查询。只要把这个查询写在回调外执行就没有性能问题,写在里面压力大的
时
候马上出问题。
查看spring的源代码发现,这两种写法唯一的区别就是,写在回调里面的
时
候,
数据库连接
未
关闭
就开启...
数据库连接池
中
关闭
连接
其实就是把
连接
归还给
数据库连接池
当中
1、不管是否出现异常,finally块中代码都会执行;
2、当try和catch中有return
时
,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此
时
并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或ca
其实主要看你是
使用
什么
连接
的
数据库
,如果没有用
连接
池的话,那么就不需要,因为当你
关闭
Connection( conn.close)
时
GC会帮你
关闭
ResultSet 和Statement ;
但是当你
使用
连接
池的
时
候就会出现异常,因为
关闭
Connection并不是物理
关闭
,而是归还
连接
池,那么不
关闭
ResultSet 和PrepareedStatement 他们就会一直存在,并且占用
数据库
的游标...
使用
Druid
连接
池
连接
数据库
,首先先写配置资源,同
时
需要导druid-1.1.10.jar包
以及
数据库
驱动mysql-connector-java-8.0.15.jar包
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/表名称?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&rewriteBatched.
今天上午在WAS6上重新部署项目,结果把最新的提交上去之后,WAS无法启动也无法
关闭
了。由于是刚接触不久对WAS不是太熟悉,查找了半天都没有找到头绪。到了下午的
时
候,仔细的查了一下SystemOut.log文件才算是找了原因,也怪自己不够细心。
项目用的SSH,在本机测试的
时
候hibernate数据源
连接
池用的C3P0,在WAS上应该用是JNDI。当数据源配置为C3P0,WAS启动初始化数据源失败而
今晚看到上了评论头条的LoveJenny写的为什么要
关闭
数据库连接
,可以不
关闭
吗?,文章写得简单易懂非常不错,而且代码贴的很到位,下面的讨论也很激烈(老赵都跑过去留言两次了,我恨)。又查看了两遍原文中的代码,我同意评论中有几位的看法,真正造成多线程并行操作
数据库
时
的
连接
问题可能是由于对SqlConnection的不当
使用
。为什么呢?再来看一下LoveJenny兄弟贴出的一段重要源码: