mysql连接池不能回避的wait timeout问题(转)

时间:2022-02-06 02:30:13

起因

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

mysql连接池不能回避的wait timeout问题(转)

看一下左下角的曲线图,突然飙高,然后在1500ms的高位不下来。经过查找日志(PS:sorry。写文章的时候日志已经被自动清除,没法截图了),发现程序卡在了getConnection这个方法上,并且卡住的时间从60s开始越来越长。

分析

getConnection是一个synchronized方法,主要是从连接池中获取数据连接!卡住时间越来越长这个现象倒是很简单就可以解释:因为getConnection是synchronized的,所以所有的线程到getConnection的时候全部等待,等待的时间越长当然时间越长了。关键在于为啥卡住呢?
当时有两种可能的想法:

  1. 连接池设置的太小,连接在使用的时候来不及被返还,导致了积压;
  2. 连接池的设置有问题,返回的连接有问题。如果是这个问题,那可能会比较难查;

第一种情况显然不会存在,查看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小一些就完全可以了。

经过更改后的程序终于恢复了正常,看一下更改后的效果:
mysql连接池不能回避的wait timeout问题(转)

科普

何为wait_timeout?
wait_timeout是mysql的一个设置,主要是用来断开不使用的数据库连接。当连接空闲的时间达到wait_timeout设置的最大值时,mysql会主动切断这个连接,以供别的客户端连接数据库。这个值一般是28800,也就是8小时。在mysql中可以通过:
show variables like “%timeout%”;
获取。
另外,当数据库主动切断连接的时候,java的mysql客户端并不知道这个连接已经被切断,所以程序并不知道其已经无效了,然后加上mysql的客户端不支持ReConnect,双重的问题叠加在一起就导致了连接池返回无效连接的可能。这是一个比较扯淡也是一个比较难以发现的问题,但是它确确实实的存在了。大家一定要多加注意。

这个值可以根据自己网络的环境和业务的并发性来调整。

mysql连接池不能回避的wait timeout问题(转)的更多相关文章

  1. 用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

  2. 实现一个协程版mysql连接池

    实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康:基于swoole的chanel. 最近事情忙,心态也有点不积极.技术倒是没有落下,只是越来越不想写博客了.想到 ...

  3. Swoole MySQL 连接池的实现

    目录 概述 代码 扩展 小结 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现. 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 ...

  4. 如何在 Swoole 中优雅的实现 MySQL 连接池

    如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...

  5. 转 Swoole】用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

  6. 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

    解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...

  7. Java Mysql连接池配置和案例分析--超时异常和处理

    前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...

  8. MySQL连接池

    1. using System; using System.Collections; using MySql.Data.MySqlClient; namespace Helper { /// < ...

  9. tomcat中使用mysql连接池的配置

    1.下载相应的jar包,添加到工程中 需要下载的包主要有commons-pool2-2.2 commons-dbcp2-2.0.1-src commons-dbcp2-2.0.1  commons-c ...

随机推荐

  1. Unique Binary Search Tree II

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  2. sql中在查询时两列合并为一列

    select  a + ' '+b  as ab from tableName 如果是有整型的(例,b字段为int类型): select a +' '+Convert(VARCHAR(50),b) a ...

  3. python相关的工具

    在使用python的时候,发现Adaconda工具包真的很不错,里面集合了很多的工具,并且,自带了很多的python常用模块 另外,PyCharm编辑器也是不错的,界面清晰,可以实现数据的可视化

  4. javascript 之作用域-06

    作用域 作用域是指变量和函数可访问范围,他规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. 作用域有两种工作模式: 静态作用域 :又称为词法作用域,在编译阶就可以决定变量的引用,由程序定义 ...

  5. 整理C&plus;&plus;面试题for非CS程序猿——更新至【48】

    结合网上的C++面试题+自己的面经,进行整理记录,for我这种非CS的程序猿.(不定期更新,加入了自己的理解,如有不对,请指出) [1] new/delete和malloc/free的区别和联系? 1 ...

  6. 解析setTimeout时间设置为0

    1.开胃菜,setTimeout为何物 首先看一下w3school上面对于setTimeout的解释 setTimeout(fn,millisec) 方法用于在指定的毫秒数后调用函数或计算表达式. 很 ...

  7. IE的变态

    1.它自身的内容动态调试功能太简陋. 2.另存成静态网页调试,发现网页代码和原先后台写的根本不一样,能稍微守点规矩行不?

  8. Robot Framework脚本在jenkins执行完之后无法查看日志

    首先确保Robot Framework Plugin已经安装好,构建结束后test result和log.html等日志文件已显示,只是无法打开查看: 修改tomcat配置:vi tomcat/con ...

  9. Django model中的class Meta详解

    通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(models.Model): bar = models.CharFi ...

  10. Ubuntu 为 root 帐号开启 SSH 登录

    1. 修改 root 密码sudo passwd root 2. 以其他账户登录,通过 sudo nano 修改 /etc/ssh/sshd_config :xxx@ubuntu:~$ su - ro ...