Tomcat Pooling DataSource数据库连接池优化(20180705)

Posted Java每日记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat Pooling DataSource数据库连接池优化(20180705)相关的知识,希望对你有一定的参考价值。

公司刚上线的项目,在某天晚上收到监控系统发送的DB监控异常的邮件,查看相关日志,发现异常信息如下:

根据异常信息排查引起异常的原因:

    mysql服务器默认的“wait_timeout”是8小时(也就是默认的值默认是28800秒),也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection,通俗的讲就是一个连接在8小时内没有活动,就会自动断开该连接。而连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。


为了确保是连接池问题,随后查看Azure Mysql 服务日志,并未发现有异常情况,排除了DB出现异常的情况,然后重新定位Tomcat 服务的日志时间段,发现在时间段内有监控DB请求也有正常返回的情况,进一步确定Mysql服务在该段时间内是正常服务的情况。


接下来根据异常原因查找解决方案,查看项目中配置的连接池参数如下:

发现testOnBorrow,testOnReturn两个参数是关闭的,但是担心该两个参数太影响性能(每次在获取连接或者返还连接时会去校验连接有效性),遂查看是否有其他参数能够保证在Mysql 8小时连接断开之前将连接从线程池中剔除,查看到以下参数:


maxAge 长整型值。连接保持时间(以毫秒计)。当连接要返回池中时,连接池会检查是否达到 now - time-when-connected > maxAge 的条件,如果条件达成,则关闭该连接,不再将其返回池中。默认值为 0,意味着连接将保持开放状态,在将连接返回池中时,不会执行任何年龄检查。

发现该参数可以设置连接的有效保持时间,可以解决Mysql因为连接时长问题断开连接但是连接池并未释放连接的问题。

另外,分析发现也有其他方式解决问题:

方案一:改小连接池始终都应保留的连接的最小数目(MinIdle),并缩小空闲连接验证的间隔(timeBetweenEvictionRunsMillis)。

方案二:增大每次空闲连接回收器线程(如果有)运行时检查的连接数量(numTestsPerEvictionRun),默认值是3(注意,网上的资料提示该参数在Tomcat Pooling DataSource不生效,但是未实际测试过).

以上是关于Tomcat Pooling DataSource数据库连接池优化(20180705)的主要内容,如果未能解决你的问题,请参考以下文章

在 tomcat 中创建名为“dataSource”的 bean 时出错

Tomcat9 抱怨找不到 javax.sql.DataSource 类的类

Tomcat数据源--DataSource&Connection Pool

server.tomcat.max-threads VS corePoolSize VS spring.datasource.tomcat.max

迁移到 JDK 11 发生错误“java.lang.NoClassDefFoundError: javax/activation/DataSource”(tomcat 9.0.12)[重复]

Aspect 失败,ClassCastException 试图切入 Tomcat DataSource getConnection