他的回复:
您好,这个问题是跟Druid连接池有关联。报错信息的源码出处是JDBC里, class QueryExecutorImpl extends QueryExecutorBase下的processResults函数,属于通信协议处理的核心状态机。原因: 因为这条连接空闲时间超过阀值,导致断连了,但是druid连接池那边的感知可能存在问题,认为驱动和druid有配合修改的点。 临时规避措施是增加druid的保活时间,或者延长session_timeout的超时时间。 即增加连接的存活时间,减少断开连接频次。 druid会在后台启动一个线程,每间隔 timeBetweenEvictionRunsMillis 设置的时间对连接池内会话进行判断,如果空闲时间大于 minEvictableIdleTimeMillis会进行关闭。但是每次只会检查现有连接数据--MinIdle数量的session。这样就导致有MinIdle个session没有进行检查, 增加driud的设置keepAlive.dataSource.setKeepAlive(true);但是每次只会检查现有连接数据--MinIdle个session。 增加此配置会对剩余连接执行validationQuery设置的SQL进行检查。可能日志还是会有Buffer is empty但是不影响应用使用了。 例如: public DataSource druid() { DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(dsDriverClassName); druidDataSource.setUrl(dsUrl); druidDataSource.setUsername(dbUser); druidDataSource.setPassword(DigestUtils.decryptIfIsEncrypted(dbPassword)); druidDataSource.setDefaultTransactionIsolation(2); druidDataSource.setRemoveAbandonedOnBorrow(true); druidDataSource.setRemoveAbandonedOnMaintenance(true); druidDataSource.setRemoveAbandonedTimeout(300); druidDataSource.setLogAbandoned(true); druidDataSource.setMaxActive(200); druidDataSource.setTestWhileIdle(true); druidDataSource.setTestOnBorrow(true); druidDataSource.setTestOnReturn(true); druidDataSource.setMinIdle(2); druidDataSource.setMaxWait(30000); druidDataSource.setMaxEvictableIdleTimeMillis(3600000); druidDataSource.setMinEvictableIdleTimeMillis(600000); druidDataSource.setValidationQueryTimeout(30000); druidDataSource.setKeepAlive(true); druidDataSource.setMaxWaitMillis(dsMaxWaitMillis); return druidDataSource; } parameters: ?currentSchema ...... &socketTimeout=10000&connectTimeout=30000 Druid开启了keepalive, socketTimeout=30, connectTimeout=30, testOnReturn关闭后,该问题即可解决。 该问题会衍生另一个网络抖动时,获取数据库连接等待15分钟后报错。 https://github.com/alibaba/druid/issues/1260