Spring Boot集成Druid异常

在Spring Boot集成Druid项目中,发现错误日志中频繁的出现如下错误信息:

discard long time none received connection. , jdbcUrl : jdbc:mysql://******?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8, version : 1.2.3, lastPacketReceivedIdleMillis : 172675

经过排查发现是Druid版本导致的异常,在1.2.2及以前版本并未出现如此异常。而在其以上版本均存在此问题,下面就来分析一下异常原因及解决方案。

异常分析

首先上面的异常并不影响程序的正常运行,但作为程序员看到程序中不停的出现异常还是难以忍受的。所以还是要刨根问底的解决一下的。

跟踪堆栈信息会发现对应的异常是从com.alibaba.druid.pool.DruidAbstractDataSource#testConnectionInternal方法中抛出的,对应的代码如下:

if (valid && isMySql) { // unexcepted branchlong 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+ ", jdbcUrl : " + jdbcUrl+ ", lastPacketReceivedIdleMillis : " + mysqlIdleMillis;LOG.error(errorMsg);return false;}}
}

上述代码中,MySqlUtils.getLastPacketReceivedTimeMs(conn) 是获取上一次使用的时间,mysqlIdleMillis 就是计算出来空闲的时间,timeBetweenEvictionRunsMillis 是常量60秒。如果连接空闲了60秒以上,那就discardConnection(holder) 丢弃这个旧连接并顺带打印了一个日志LOG.warn(errorMsg)。

原理追踪

在上述代码中,我们看到进入该业务逻辑是有前提条件的,也就是valid和isMySql变量同时为true。isMySql为true是必须的,我们使用的本身就是Mysql数据库。那么是否可以让valid为false呢?这样不就不会进入该业务处理了吗?

来看看valid的来源,还是在该方法的上面:

boolean valid = validConnectionChecker.isValidConnection(conn, validationQuery, validationQueryTimeout);

我们找到validConnectionChecker的Mysql实现子类MySqlValidConnectionChecker,该类中对isValidConnection的实现如下:

public boolean isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) throws Exception {if (conn.isClosed()) {return false;}if (usePingMethod) {if (conn instanceof DruidPooledConnection) {conn = ((DruidPooledConnection) conn).getConnection();}if (conn instanceof ConnectionProxy) {conn = ((ConnectionProxy) conn).getRawObject();}if (clazz.isAssignableFrom(conn.getClass())) {if (validationQueryTimeout <= 0) {validationQueryTimeout = DEFAULT_VALIDATION_QUERY_TIMEOUT;}try {ping.invoke(conn, true, validationQueryTimeout * 1000);} catch (InvocationTargetException e) {Throwable cause = e.getCause();if (cause instanceof SQLException) {throw (SQLException) cause;}throw e;}return true;}}String query = validateQuery;if (validateQuery == null || validateQuery.isEmpty()) {query = DEFAULT_VALIDATION_QUERY;}Statement stmt = null;ResultSet rs = null;try {stmt = conn.createStatement();if (validationQueryTimeout > 0) {stmt.setQueryTimeout(validationQueryTimeout);}rs = stmt.executeQuery(query);return true;} finally {JdbcUtils.close(rs);JdbcUtils.close(stmt);}}

我们可以看到上述方法中有三个返回的地方:第一个连接已关闭;第二个使用ping的形式进行检查;第三,使用select 1的方式进行检查。而使用ping的形式检查时,无论是否抛异常都会返回true。这里我们禁用该模式即可。

进入ping的业务逻辑主要靠变量usePingMethod来判断,追踪代码会发现在这里进行的设置:

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.mysql.usePingMethod设置为false即可禁用该功能。

禁用Ping Method

找到了问题的根源,那么剩下的就是如何禁用了,通常有三种形式。

第一,在启动程序时在运行参数中增加:-Ddruid.mysql.usePingMethod=false。

第二,在Spring Boot项目中,可在启动类中添加如下静态代码快:

static {System.setProperty("druid.mysql.usePingMethod","false");
}

第三,类文件配置。在项目的DruidConfig类中新增加:

/*
* 解决druid 日志报错:discard long time none received connection:xxx
* */
@PostConstruct
public void setProperties(){System.setProperty("druid.mysql.usePingMethod","false");
}

至此,已可以成功关闭该功能,异常信息再也不会出现了。

为什么要清空空闲60秒以上的连接

猜测,阿里给数据库设置的数据库空闲等待时间是60秒,mysql数据库到了空闲等待时间将关闭空闲的连接,以提升数据库服务器的处理能力。

MySQL的默认空闲等待时间是8小时,就是「wait_timeout」的配置值。如果数据库主动关闭了空闲的连接,而连接池并不知道,还在使用这个连接,就会产生异常。

面试系列

  • 《面试题:聊聊TCP的粘包、拆包以及解决方案》
  • 《面试题:重写equals方法为什么通常会重写hashcode方法?》
  • 《面试官:如何找出字符串中无重复最长子串?》
  • 《还不懂Java的泛型?只用这一篇文章,保证你面试对答如流》
  • 《面试题:将字符串反转的8种方法,你能想到几种?》

程序新视界
公众号“程序新视界”,一个让你软实力、硬技术同步提升的平台,提供海量资料

Spring Boot集成Druid异常discard long time none received connection.相关推荐

  1. Spring Boot 集成 Druid 监控数据源

    关注"Java后端技术全栈" 回复"面试"获取全套大厂面试资料 Druid 介绍 Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池.插件框架和 ...

  2. spring boot 集成druid数据库连接池,并打印sql

    spring boot 2.x 集成druid pom文件配置 <dependencies><dependency><groupId>org.springframe ...

  3. Spring Boot集成Druid监控

    package com.xxxxxxx.framework.datasource.druid;import com.alibaba.druid.support.http.WebStatFilter;i ...

  4. Spring Boot 集成MyBatis

    Spring Boot 集成MyBatis Spring Boot 系列 Spring Boot 入门 Spring Boot 属性配置和使用 Spring Boot 集成MyBatis Spring ...

  5. 有手就行的 Spring Boot 集成 Shiro

    前言   Apache Shiro 是 Java 的一个安全框架.目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Se ...

  6. Spring Boot 使用 Druid 连接池详解

    Spring Boot 使用 Druid 连接池详解 Alibaba Druid 是一个 JDBC 组件库,包含数据库连接池.SQL Parser 等组件,被大量业务和技术产品使用或集成,经历过严苛的 ...

  7. Spring Boot使用Druid和监控配置

    完美与Spring Boot集成. 1.编写Spring Boot Druid配置类 DruidDataSourceProperties.java package org.paascloud.ops. ...

  8. Spring Boot下Druid连接池的使用配置分析

    引言: 在Spring Boot下默认提供了若干种可用的连接池,Druid来自于阿里系的一个开源连接池,在连接池之外,还提供了非常优秀的监控功能,这里讲解如何与Spring Boot实现集成. 1.  ...

  9. Spring Boot 集成 Mybatis 实现双数据源

    转载自   Spring Boot 集成 Mybatis 实现双数据源 这里用到了Spring Boot + Mybatis + DynamicDataSource配置动态双数据源,可以动态切换数据源 ...

最新文章

  1. 揭秘互联网人群层级,你属于第几级?
  2. Android新权限机制 AppOps
  3. SpringBoot+Jquery实现前后端数据交互
  4. 【NLP】EMNLP'21 | 让压缩语言模型自动搜索最优结构!
  5. 全国计算机等级考试题库二级C操作题100套(第02套)
  6. win7内存占用过高怎么处理
  7. Kylin修改默认hbase namespace命名空间default的解决方案
  8. Sliverlight中使用Path绘制复杂几何图形
  9. mysql5.7不区分大小写_转载:mysql5.7设置不区分大小写
  10. 数据科学包2-pandas快速入门1
  11. 还不会回答Spring Boot和Spring MVC的关系?大厂Java高级面试官告诉你答案!
  12. 答粉丝问|火狐浏览器插件简介
  13. Android手机游戏开发入门教程
  14. 主数据管理(MDM)与元数据管理
  15. python函数返回值可以有多个吗_Python函数中如何返回多个值?(代码示例)
  16. 四川大学计算机专业调剂,四川大学计算机学院(软件学院)研究生调剂
  17. 51单片机定时器中断按键消抖(无延时)
  18. 优化| 手把手教你学会杉树求解器(COPT)的安装、配置与测试
  19. 分析报告_问题界定篇
  20. outlook的archive pst丢失后

热门文章

  1. 移动端touch事件和click事件的区别
  2. 网络系统设计过程中,物理网络设计阶段的任务是(70)。【答案】A
  3. [CSCCTF 2019 Qual] FlaskLight
  4. 办公室必备-上班偷看小说利器
  5. 终于有一篇能让小白更容易理解GC算法的文章了
  6. 蓝桥杯刷题日记 更新到2022/2/5
  7. 成长型企业的好帮手:超融合小身材却有大能量
  8. 《非Pad勿扰》风靡平板电脑界
  9. python怎么编写对称图案_python – 无论matplotlib中的箭头角度如何,都使箭头形状对称...
  10. 谈谈运营经验:颠覆式创新