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 ...
随机推荐
- 【QT】QPixmap和QImage在QLabel显示一张图像
#include <QPixmap> void Dialog::on_Button1_clicked() { QPixmap img; img.load("1.bmp" ...
- JQuery Easyui引入easyui-lang-zh_CN.js后出现乱码的问题解决方法
最近使用Easyui做项目,发现引入easyui-lang-zh_CN.js单元后页面会出现乱码,无论设置<meta>.还是Response都不能解决问题.用记事本打开easyui-lan ...
- 仿迅雷播放器教程 -- duilib界面(13)
经过了这么多篇文章的讲解,相信大家也对界面库有一定了解了,用一个新的界面库,肯定要对它进行全方位考察.鉴于公司目前所有的产品都是MFC做的,全部转换成duilib肯定不现实,并且公司的很多项目逻辑和界 ...
- duilib进阶教程 -- Label控件的bug (8)
上个教程说到了TreeView的文字不能垂直居中的问题,而我们用LabelUI其实是可以垂直居中的,为什么不说是TreeView的bug,而说是Label控件的bug呢?因为影响TreeView垂直居 ...
- [IR] XML Compression
Ref: https://www.ibm.com/developerworks/cn/xml/x-datacompression/ Language-Equivalent (类似路径压缩 ) root ...
- Texture::setUnRefImageDataAfterApply
当该值设置为true时,OSG在应用过该纹理对象后(apply),自动释放其对Image对象的引用,以减少内存占用
- 10.24CRM完成
2018-10-24 16:16:59 已经完成了crm项目: 项目做完了,这几天可以安静整理Django啦!!!把博客整理一下! 然后再过几天针就可以回学校啦!! 今天程序员节 节日快乐!hell ...
- 面向对象。OOP三大特征:封装,继承,多态。 这个讲的是【封存】
class Ren { private $name; private $sex; private $age; //年龄必须在18-50之间 function __constuct($v) { $thi ...
- TensorRT 不支持Tensorflow的操作有如下
tf.unpack, tf.slice, tf.tile, tf.expand_dims, tf.fill, tf.cast, tf.floor_div, tf.range 比较坑,所以你必须限制你的 ...
- CSS中隐藏内容的3种方法
CSS中隐藏内容的3种方法 一般有:隐藏文本/图片.隐藏链接.隐藏超出范围的内容.隐藏弹出层.隐藏滚动条.清除错位和浮动等. 1.使用display:none来隐藏所有内容 display:none可 ...