当前位置: 首页 > 科技观察

微服务架构下,MySQL读写分离后,Druid连接池参数优化实践_0

时间:2023-03-16 11:42:45 科技观察

前言最近使用MHA完成Mysql读写分离后,时不时有用户反映程序“一般异常”被在后台发布文章时报告。故障排查,其中涉及JDBC连接池参数的应用和Mysql参数调整问题。问题回顾异常日志描述:从异常信息反映来看,问题有两个关键点。数据库连接池超时设置大于wait_timeout日志提示。这个异常可以通过验证数据库连接或者设置:autoReconnect=true来避免。从以上两点我们可以推测出第1点,应用数据库连接池的超时参数设置有问题。2、安装Mysql数据库时,Mysql的内部参数wait_timeout没有针对实际场景进行优化。问题定位wait_timeout参数的具体用途wait_timeout的具体含义是在服务器关闭非交互连接前等待的Active秒数。在MySQL的默认配置中,wait_timeout的初始值为28800秒,也就是8小时。wait_timeout超时时间设置过大,会在MySQL管理系统中产生大量SLEEP进程,无法及时释放,导致服务器系统性能下降;同时,如果参数设置的太小,一些事务将不会被Mysql处理,出现连接不可用状态。也就是说如果数据库连接Connection在wait_timeout设置期间一直处于空闲等待状态,mysql会在内部自动关闭连接,但应用程序无法感知,仍然认为连接池合法持有连接。当应用端再次使用该连接进行数据库操作时,就会产生上述异常错误。应用端Druid数据库连接池参数排查,发现连接池有个MaxWait参数设置过大:60000毫秒druidDataSource.setMaxWait(60000)然后在CSDN上,发现有同事遇到了同样的问题:发现数据库等待超时(wait_timeout)是28800s,也就是8小时,应用连接池参数max-wait:30000,所以项目判断连接可用,而mysql判断连接不可用,导致一个连接失败。解决方案根据以上分析思路,我们查看Mysql生产库,发现Mysql默认的超时时间(wait_timeout)也是28800s,但是应用层连接池的MaxWait参数设置为60000,所以我将MaxWait参数设置为10000,小于Mysql超时时间(wait_timeout):28800,在测试环境等待8小时后,报错信息消失。其他扩展思路(来源网络)思路一:在jdbc-url后面加上&autoReconnect=true,使用后无效。找到的解决方案只适用于Mysql4之前的版本。有效思路二:让mysql回收空闲连接的时间更长,mysql默认回收时间为8小时,可以在mysql目录下的my.ini中添加如下配置,将时间改为1天。单位是秒,最大好像是24天。这种配置会拖累数据库的性能,所以被弃用了。思路三:配置druid连接池,使用validation-querytest-on-borrow:truetest-while-idle:true三个属性,每次获取数据库连接时判断连接是否可用。同时设置druidDataSource.setPhyTimeoutMillis参数连接的最大存活时间,默认为-1(不限制物理连接时间),从连接创建开始计算。如果超过这个时间,就会被清除。druidDataSource.setPhyTimeoutMillis(15000);参考当前项目中的例子对于趋于稳定的连接池参数实际优化参考如下:Druid连接池参数官方说明: