[alibaba/druid]为什么只有mysql在getConnection测试连接是否存活时,会判断连接是否超过空闲时间?

2025-11-11 786 views
0

代码片段如下:

                if (valid && isMySql) { // unexcepted branch
                    long lastPacketReceivedTimeMs = MySqlUtils.getLastPacketReceivedTimeMs(conn);
                    if (lastPacketReceivedTimeMs > 0) {
                        long mysqlIdleMillis = currentTimeMillis - lastPacketReceivedTimeMs;
                        if (lastPacketReceivedTimeMs > 0 //
                                && mysqlIdleMillis >= timeBetweenEvictionRunsMillis) {
                            discardConnection(holder);
                            String errorMsg = "discard long time none received connection. "
                                    + ", jdbcUrl : " + jdbcUrl
                                    + ", version : " + VERSION.getVersionNumber()
                                    + ", lastPacketReceivedIdleMillis : " + mysqlIdleMillis;
                            LOG.warn(errorMsg);
                            return false;
                        }
                    }
                }

当开启了testWhileIdle时,getConnection会先判断isValidConnection。当返回true时,会进入上面的代码。如果超过空闲等待时间,直接抛弃旧连接,建立新连接。但实际上这个连接是可用的,因为isValidConnection已经返回true了。

现在我们的应用和数据库处于高网络延迟的场景下,对这种重新创建物理连接的操作非常敏感,所以想问下这里的逻辑是出于什么考虑?为何不能复用已经判断可用的连接?

回答

1

tcp 机制了解下,这个isValidConnection 只能保证连接池中可用,如果网络问题链接断开了,这个校验不出来

1

tcp 机制了解下,这个isValidConnection 只能保证连接池中可用,如果网络问题链接断开了,这个校验不出来

跟tcp没关系吧,isValidConnection 里面实现就是ping或者select 1,如果成功的话不就代表网络没问题吗 我感觉他应该是想顺便清空超过空闲时间的连接,毕竟ping可能ping通但是实际已经很长时间没用过了

7

tcp 机制了解下,这个isValidConnection 只能保证连接池中可用,如果网络问题链接断开了,这个校验不出来

跟tcp没关系吧,isValidConnection 里面实现就是ping或者select 1,如果成功的话不就代表网络没问题吗 我感觉他应该是想顺便清空超过空闲时间的连接,毕竟ping可能ping通但是实际已经很长时间没用过了

他这段代码应该是为了解决8小时超时用的,或者是处理动态清空 空闲链接用的