最新项目中用的druid链接数据库遇到一个困扰好久的问题mysql
1 开始用的druid版本是1.1.22版本,因为业务需求,单个链接须要执行好久,理论上不须要用到自动回收,但为了安全,仍是加了自动回收,时间设置的2个小时。sql
问题来了,程序常常报The last packet successfully received from the server was XXXXX milliseconds ago. The last packet sent successfully to the server was 0 mill
iseconds ago错误,网上搜索了下答案,有说配置项,改数据库事件设置,试过都没有解决,后续看到https://cloud.tencent.com/developer/article/1397508 分析,以为有必定道理,就开始后续之路数据库
2.druid包升级到1.2.2,原来的问题是没有了,新的问题出现了,discard long time none received connection,又继续网上搜索答案,出来的结果一塌糊涂,不少说版本回退到1.1.22,内心不禁的说wc,这...安全
有点扯,继续进行搜索测试,修改配置项validationQuery,修改testWhileIdle,修改...继续测试,问题依旧,又搜索到运行时添加druid.mysql.usePingMethod=false,可是没说怎样添加,没办法下载源码进行查看,导入源码后发现以下:ide
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; } } }
这在配置中加timeBetweenEvictionRunsMillis:1800000 就能够了,我的理解是一次操做数据库大于这个时间就会被清除,更直观些就是查询或其余操做在数据库执行时间,这里单位是毫秒。测试
紧接着查看源码druid.mysql.usePingMethod=false这个设置,既然网上有人说,就看看好使不,源码以下:ui
configFromProperties(System.getProperties()); } @Override public void configFromProperties(Properties properties) { String property = properties.getProperty("druid.mysql.usePingMethod"); if ("true".equals(property)) { setUsePingMethod(true); } else if ("false".equals(property)) { setUsePingMethod(false); } }
druid加载System.getProperties(),查看属性中的druid.mysql.usePingMethod的对应值,若是false,就不用ping方法,否者用ping方法,进一步查看不用ping方法就是用默认select 1,System.getProperties()查看了下通常是系统的一些参数,可是能够put(key,value),程序启动时间加载进去就能够,项目中用到了定时器(根据本身项目写就能够,加载一次就ok了),就在初始化时间设置了具体值,代码以下:spa
public void contextInitialized(ServletContextEvent arg0) { try { System.getProperties().put("druid.mysql.usePingMethod", "false"); // 获取Scheduler实例 scheduler = new StdSchedulerFactory().getScheduler(); ...
而后取消timeBetweenEvictionRunsMillis设置进行测试,程序跑1个小时没有任何问题,到此问题解决。code
druid我的使用总结:server
1.The last packet successfully received from the server was问题升级jar包,我是升级到1.2.2版本
2.discard long time none received connection问题不应程序状况下设置timeBetweenEvictionRunsMillis参数(注意是毫秒),改程序下加System.getProperties().put("druid.mysql.usePingMethod", "false")
druid默认使用usePingMethod方法,此方法并不会更新链接返回时间,致使lastPacketReceivedTimeMs大于timeBetweenEvictionRunsMillis
网上其余的方法感受要不理解太深,没有给出具体实现,要不就是复制粘贴的,但愿对遇到此问题的人有所帮助。