解决: discard long time none received connection.

问题现象

本人使用的druid版本为1.2.2,再开发过程中,Console控制台总是时不时打印一段 :
在这里插入图片描述

问题原因

找到 com.alibaba:druid1.2.2(自己的对应版本)包下的pool文件夹,DruidAbstractDataSource类里的 testConnectionInternal 方法,我们来看一眼原源码,如下图所示:
在这里插入图片描述

调用一个名为MySqlUtils的工具类中的方法getLastPacketReceivedTimeMs,传入当前的数据库连接
conn作为参数。这个方法用于获取从数据库服务器接收到最后一个数据包的时间戳(以毫秒为单位)。
long lastPacketReceivedTimeMs = MySqlUtils.getLastPacketReceivedTimeMs(conn);:

如果获取到的最后一个数据包的时间戳大于 0,表示曾经接收到过数据包。
if (lastPacketReceivedTimeMs > 0) {... }:

计算从当前时间到最后一个数据包接收时间的时间差,即连接的空闲时间(以毫秒为单位)。
long mysqlIdleMillis = currentTimeMillis - lastPacketReceivedTimeMs;:

注:timeBetweenEvictionRunsMillis是一个固定的值(DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 60 * 1000L;) 

这个时间间隔是配置的连接在连接池中被认为闲置过久而应该被丢弃的时间阈值。
if (lastPacketReceivedTimeMs > 0 && mysqlIdleMillis >= timeBetweenEvictionRunsMillis) {... }:

调用一个方法来丢弃当前的数据库连接,将其从连接池中移除或者进行其他处理以释放资源。
discardConnection(conn);

创建一个错误字符串,包含了丢弃连接的原因(长时间未收到数据包)、数据库连接 URL 和连接的空闲时间。
String errorMsg = "discard long time none received connection. " + ", jdbcUrl : " + jdbcUrl + ", jdbcUrl : " + jdbcUrl + ", lastPacketReceivedIdleMillis : " + mysqlIdleMillis;

使用日志记录器记录错误消息,级别为错误级别。
LOG.error(errorMsg);

综上所述代码,大概意思就是:连接空闲超过60s,就丢弃并且打印一条warn级日志。
阿里将数据库的空闲等待时间设置为 60 秒。在 MySQL 数据库中,当达到空闲等待时间时,数据库会关闭空闲连接,以提升数据库服务器的处理能力。MySQL 的默认空闲等待时间为 8 小时,即「wait_timeout」的配置值。如果数据库主动关闭了空闲连接,而连接池却不知情,仍在使用该连接,就会引发异常。

解决办法

方法一:修改Druid版本号

建议升级成1.2.9的版本。1.2.9之后就不会出现那个日志打印了。
在这里插入图片描述

方法二:修改配置文件(注:有的版本不支持该属性)

在配置文件中增加“use-ping-method”属性 设置为false
是否使用 ping 方法来检测数据库连接是否有效。该参数的默认值为 false,默认不使用 ping方法。

在这里插入图片描述

方法三:在DruidConfig配置类中添加方法设置属性

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值