千家信息网

分析MyBatis空闲连接探测的机制

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"分析MyBatis空闲连接探测的机制",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"分析MyBatis空闲连接探测的机制"吧!最近碰
千家信息网最后更新 2026年11月03日分析MyBatis空闲连接探测的机制

这篇文章主要讲解了"分析MyBatis空闲连接探测的机制",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"分析MyBatis空闲连接探测的机制"吧!

最近碰到个现象,某个应用,每天在21:00-23:00才会执行,连接数据库执行操作,间隔性出现连接超时的错误,

Connection timed out (Read failed)

因为应用和数据库是跨网段,咨询了下,防火墙超时时间配置的是30分钟,应用用的MyBatis连接池,相关配置如下,

相关参数解释,如下所示,

POOLED– 这种数据源的实现利用"池"的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。这种处理方式很流行,能使并发 Web 应用快速响应请求。

除了上述提到UNPOOLED下的属性外,还有更多属性用来配置POOLED的数据源:

poolMaximumActiveConnections – 在任意时间可存在的活动(正在使用)连接数量,默认值:10

poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。

poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)

poolTimeToWait – 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直失败且不打印日志),默认值:20000 毫秒(即 20 秒)。

poolMaximumLocalBadConnectionTolerance – 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程。如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过 poolMaximumIdleConnections 与 poolMaximumLocalBadConnectionTolerance 之和。默认值:3(新增于 3.4.5)

poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是"NO PING QUERY SET",这会导致多数数据库驱动出错时返回恰当的错误消息。

poolPingEnabled – 是否启用侦测查询。若开启,需要设置 poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。

poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。

P.S.

https://mybatis.org/mybatis-3/zh/configuration.html#environments

按照这字面意思,一开始我们理解poolPingConnectionsNotUsedFor参数控制的是连接多久没用,即处于空闲状态,在参数poolPingEnabled开启时,就会执行poolPingQuery定义的SQL主动探测。

如果按照这理解,poolPingConnectionsNotUsedFor设置了3000,即3秒,远小于30分钟防火墙超时的设置,不应该出现连接超时的现象。

我们怀疑过防火墙的配置,但从应用端看,并不是所有的请求都超时,而且防火墙端,没看到什么异常。数据库层,应该未设置过相关的配置。

原因是什么?

作为一款成熟的产品,不太可能因为bug,更多还是对他的理解存在偏差。

下载3.3.0的源码,链接如下,

https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.3.0

搜索这几个参数所在的文件,找到了PooledDataSource类,可以看到这三个参数都设置了初始值,

看下这个pingConnection方法,

如果连接未关闭,判断逻辑如下,

1. poolPingConnectionsNotUsedFor的值>=0;

2. getTimeElapsedSinceLastUse()>poolPingConnectionsNotUsedFor;

getTimeElapsedSinceLastUse()定义如下,

lastUsedTimestamp是在构造函数PooledConnection中定义的,

PooledConnection会在获取连接(popConnection)和回收连接(pushConnection)的时候调用,获取连接和回收连接则会被getConnection()和invoke()调用,因此,(2)的意思是当前这个连接空闲的时间是否大于这个参数poolPingConnectionsNotUsedFor定义的时间。

3. 如果满足条件(1)和(2),则会执行poolPingQuery的SQL,此处就是"select 1 from dual",如果执行失败,会关闭这个连接,

从应用日志,能看到这些信息,

Testing connection 0000000000 ... Execution of ping query 'select 1 from dual' failed:  Connection timed out (Read failed)

这个问题的关键,就是这个pingConnection,在什么时候调用,就决定了poolPingConnectionsNotUsedFor什么时候起作用,可以看到,他是在这个isValid的方法中调用的,

而这个isValid是在每次获取连接和回收连接时调用的,换句话说,他是被动调用,并不是我们认为的空闲时主动调用,所以这个应用,只是晚上会跑,空闲连接超过30分钟是很正常的,

应用开了debug,这两段之间的间隔时间,就是得到超时连接的时间,

经过单线程测试,大约在15分钟,

因此,对这种testOnBorrow的连接探测机制,各有优缺点,优点就是会在一定程度保证应用正常的业务请求得到可用的连接,毕竟不可用的连接都已经被poolPingQuery定义的SQL测试了,一般情况下,不会让正常的业务请求出现报错,除非连接池没任何可用的连接。缺点就是如果配置的poolPingConnectionsNotUsedFor很小,某些请求都会在执行之前先进行验证,但是换个角度,如果是高并发,只要参数不是0,一般可能都不会满足需要验证的条件,如果设置为0,就可能会有很多pingQuery定义的SQL执行。而且,如果像上述单线程的操作,他会一个连接一个连接的尝试,等待一个连接出现超时错误的时间间隔是15分钟,这就很低效了。

对连接池的选择和配置,确实得结合实际场景需求来决策。

通过这个问题,至少让我明白,"自以为对的"机制正确还是错误,还是看他的实现,这才是最可靠的验证,而且,通过他的逻辑,可以让我们借鉴一些设计路径,多考虑他这么做背后的意义和影响,更有助我们将其用到正确的场景。

感谢各位的阅读,以上就是"分析MyBatis空闲连接探测的机制"的内容了,经过本文的学习后,相信大家对分析MyBatis空闲连接探测的机制这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

时间 空闲 数据 应用 配置 参数 机制 探测 就是 数据库 线程 尝试 分析 错误 防火墙 侦测 防火 验证 属性 情况 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 天津市摩尔互联网科技 云信互联网科技有限公司 互联网科技资迅 互联网医疗科技 互联网金融科技平台 赫美联合互联网科技 左右互联网络科技 山东吉时兔互联网科技有限公司 互联网企业和科技型企业 崇明区互联网教育科技诚信经营 互联网公司黑科技创始人 玉溪新华互联网科技好不好 烟台灵鸽互联网科技有限公司 产业互联网科技服务公司 互联网科技数字货币 互联网科技包装股份有限公司上市 互联网科技收购价值 易租星互联网科技有限公司 绵阳真晨互联网科技有限公司 株洲百竞科技的互联网营销顾问 科技互联网 南京欣网互联网络科技 上海卓越科技互联网 互联网通讯科技 四川狮子座互联网科技 汉立互联网科技有限公司联系电话 互联网系的金融科技公司 贵州叶脉互联网科技有限公司所属行业 科技类公司包括互联网吗 广州燕处互联网科技有限公司
0