数据库连接池打印日志:discard long time none received connection


  • 日志详情:
c.a.druid.pool.DruidAbstractDataSource   : discard long time none received connection. , jdbcUrl : XXXX
  • 产生原因:

查看com.alibaba.druid源码可知:

mysqlIdleMillis =当前时间-上次有收到包数据时间,即最近等待时间
当等待时间超过60s(默认,可改),则丢弃。
if (valid && isMySql) { // unexcepted branch
                    long lastPacketReceivedTimeMs = MySqlUtils.getLastPacketReceivedTimeMs(conn);
                    if (lastPacketReceivedTimeMs > 0) {
                        long mysqlIdleMillis = currentTimeMillis - lastPacketReceivedTimeMs;
                        if (lastPacketReceivedTimeMs > 0 //
                                && mysqlIdleMillis >= timeBetweenEvictionRunsMillis) {//当mysqlIdleMillis >= 60s
                            discardConnection(holder); //关闭连接
                            String errorMsg = "discard long time none received connection. "
                                    + ", jdbcUrl : " + jdbcUrl
                                    + ", version : " + VERSION.getVersionNumber()
                                    + ", lastPacketReceivedIdleMillis : " + mysqlIdleMillis;
                            LOG.warn(errorMsg);
                            return false;
                        }
                    }
                }
  • 解决方案

给druid加一条配置: druid.mysql.usePingMethod=false

原理是让验证空闲连接不使用mysql的ping方法,而是使用select 1,这样每次进入上面提到的源码中时,时间都会刷新,就不会超过60s啦。
具体做法有两种:

  1. 运行时配置
    • 即在运行参数中增加 : 在运行参数中增加:-Ddruid.mysql.usePingMethod=false
  2. 类文件配置
    • 在项目的DruidConfig类中新增加
/*
* 解决druid 日志报错:discard long time none received connection:xxx
* */
@PostConstruct
public void setProperties(){
    System.setProperty("druid.mysql.usePingMethod","false");
}