mysql连接池不能回避的wait timeout问题(转)
起因
我们的项目组一直在使用albianj作为开发框架在开发应用。使用至今倒也是没有出现很大的问题,但最近加过监控的接口基本上都会在使用一段时间后,突然之间执行数据库操作变得很慢。虽然会变慢,但持续的时间比较短,一般1分钟左右,然后会自动恢复正常。但是过了一段时间,这个现象又会出现,周而复始。从监控看,发生的时间点并无规律,有的时候一天发生3次,有的也会有4-5次。虽然从规律上并无法去查找,那就只能从别的地方想办法:增加一些详细的日志,从日志上看一下问题所在。
详细日志版本刚刚上去,立刻就发生问题了。如下图:

看一下左下角的曲线图,突然飙高,然后在1500ms的高位不下来。经过查找日志(PS:sorry。写文章的时候日志已经被自动清除,没法截图了),发现程序卡在了getConnection这个方法上,并且卡住的时间从60s开始越来越长。
分析
getConnection是一个synchronized方法,主要是从连接池中获取数据连接!卡住时间越来越长这个现象倒是很简单就可以解释:因为getConnection是synchronized的,所以所有的线程到getConnection的时候全部等待,等待的时间越长当然时间越长了。关键在于为啥卡住呢?
当时有两种可能的想法:
- 连接池设置的太小,连接在使用的时候来不及被返还,导致了积压;
- 连接池的设置有问题,返回的连接有问题。如果是这个问题,那可能会比较难查;
第一种情况显然不会存在,查看albianj的数据库配置,所有的配置对于连接池的设置MinSize为5,MaxSize为20.对于我们的应用来说肯定是够用的。那么就是第二个问题了。
首先检查连接复用问题,对于数据库的连接字符串,我已经增加了重连的设置:
autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&maxReconnect=3&autoReconnectForPools=true
显然autoReconnect没有起作用。查了一下mysql的客户端说明,后背发凉。基本上的大意翻译过来是这样的“即使在创建Mysql时url中加入了autoReconnect=true参数,一但这个连接两次访问数据库的时间超出了服务器端wait_timeout的时间限制,还是会CommunicationsException: The last packet successfully received from the server was xxx milliseconds ago. ”。赶快去查一下日志,发现并没有报这个错误。那应该不是这个问题。
既然不能重连接,那么最大的可能就是“返回的连接本来可能就是有问题的,但是程序确认为没有问题”。发生这种问题的最大可能应该就是:数据库连接池的连接过期时间大于mysql的wait_timeut设置。查了一下代码,发现我们默认的数据库连接池连接过期时间是300-30=270s。再去问一下DBA木木,让他查一下线上的数据库wait_timeout设置,被告知是180.瞬间懵逼:连接池的生命周期时间远远参与真实的连接生命周期时间。
原因是找到了,但是这个问题其实前一段时间已经发现并且已经改过了。因为去年我记得很清楚:又一次我们的probactor(job调度系统)报了上文提到的CommunicationsException异常,后来找到了问题就是因为程序对于连接池中连接的alivetime长于数据库的wait timeout设置,随后我千叮咛万嘱咐这个设置必须要小心小心再小心,但这次还是中招了。因为连接池和网络的问题,我们有同事直接放弃连接池,改用每次连接数据库。放弃连接池确实能解决连接不会出现问题,但是侧面也导致了wait_timeout被设置的过小了。但其实只要把连接池中连接的过期时间设置的比wait_timeout小一些就完全可以了。
经过更改后的程序终于恢复了正常,看一下更改后的效果:

科普
何为wait_timeout?
wait_timeout是mysql的一个设置,主要是用来断开不使用的数据库连接。当连接空闲的时间达到wait_timeout设置的最大值时,mysql会主动切断这个连接,以供别的客户端连接数据库。这个值一般是28800,也就是8小时。在mysql中可以通过:
show variables like “%timeout%”;
获取。
另外,当数据库主动切断连接的时候,java的mysql客户端并不知道这个连接已经被切断,所以程序并不知道其已经无效了,然后加上mysql的客户端不支持ReConnect,双重的问题叠加在一起就导致了连接池返回无效连接的可能。这是一个比较扯淡也是一个比较难以发现的问题,但是它确确实实的存在了。大家一定要多加注意。
这个值可以根据自己网络的环境和业务的并发性来调整。
mysql连接池不能回避的wait timeout问题(转)的更多相关文章
- 用swoole简单实现MySQL连接池
MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...
- 实现一个协程版mysql连接池
实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康:基于swoole的chanel. 最近事情忙,心态也有点不积极.技术倒是没有落下,只是越来越不想写博客了.想到 ...
- Swoole MySQL 连接池的实现
目录 概述 代码 扩展 小结 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现. 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 ...
- 如何在 Swoole 中优雅的实现 MySQL 连接池
如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...
- 转 Swoole】用swoole简单实现MySQL连接池
MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...
- 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。
解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...
- Java Mysql连接池配置和案例分析--超时异常和处理
前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...
- MySQL连接池
1. using System; using System.Collections; using MySql.Data.MySqlClient; namespace Helper { /// < ...
- tomcat中使用mysql连接池的配置
1.下载相应的jar包,添加到工程中 需要下载的包主要有commons-pool2-2.2 commons-dbcp2-2.0.1-src commons-dbcp2-2.0.1 commons-c ...
随机推荐
- [TensorBoard] *Cookbook - Tensorboard
Ref: https://www.tensorflow.org/get_started/summaries_and_tensorboard 可视化对于Training的重要性,不言而喻. 代码示范 # ...
- Python判断字符集
Python利用第三方库chardet可以判断字符集. https://chardet.readthedocs.io >>> import urllib >>> r ...
- 在WPS中删除整行的快捷键是什么?
选中需要删除的行,(方法:点击最左侧的行号):按快捷键Ctrl+-(按着Ctrl不放,再按小键盘的减号“-”),“-”是删除,“+”是插入,选中行,是对行操作,选中列就是对列操作,选中单元格,就是单元 ...
- [原]Jenkins(十一)---jenkins使用管理员admin创建用户和分配权限
/** * lihaibo * 文章内容都是根据自己工作情况实践得出. * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horizonli/p/533 ...
- [原]openstack-kilo--issue(十六) instance can't get ip 虚拟机不能得到ip(1)
=====问题点:vm instance不能正常获取ip地址(此时用户是:admin) =======不一样的点:如果使用用户demo用户,启动一个vm,同样的image这个时候就能正确获取ip == ...
- centos7 LANMP 安装
没有开头语. 操作系统:CentOs7.6 64位. Nginx:系统自带 nginx1.12.2包. Mysql:系统自带 MariaDB 5.6 ,更换为 Mysql5.6 PHP:系统php5. ...
- jquery-1.11.2.min.js
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ !function(a,b){& ...
- CentOS开机自启动/etc/rc.local不执行的解决办法
放置在开机自启动里面没有自动启动 查看文件/etc/rc.local发现是一个软连接 修改源文件的执行权限即可 chmod 755 /etc/rc.d/rc.local 查看日志可以看到开机自启动过程 ...
- np.unravel_index
>>> np.unravel_index([22, 41, 37], (7,6)) (array([3, 6, 6]), array([4, 5, 1]))>>> ...
- weblogic启动项目,设置内容、设置的数据源链接不生效
昨天坑自己了一把,把weblogic的数据库连接方式由jdbc改成了jndi,然后不生效,还是走之前jdbc的连接地址. 因为数据库用户之前权限有问题,所以一直纠结于这个地方,忘记了缓存的原因. 后来 ...