Druid+mysql+mybatis做定时批量操作出现CommunicationsException: Communications link failure
Posted baby123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Druid+mysql+mybatis做定时批量操作出现CommunicationsException: Communications link failure相关的知识,希望对你有一定的参考价值。
最近使用Druid+mysql+mybatis实现定时批量操作,过一段时间就会抛出
2019-08-21 11:43:51.731 [task-3] ERROR com.alibaba.druid.pool.DruidPooledStatement - CommunicationsException, druid version 1.1.17, jdbcUrl : jdbc:mysql://localhost:3306/bim?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false, testWhileIdle true, idle millis 8007, minIdle 5, poolingCount 4, timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 8007, driver com.mysql.cj.jdbc.Driver, exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter
2019-08-21 11:43:51.732 [task-3] ERROR com.alibaba.druid.pool.DruidDataSource - discard connection
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet successfully received from the server was 8,003 milliseconds ago. The last packet sent successfully to the server was 8,003 milliseconds ago.
查了很多资料有人说要修改 mysql连接的超时时间,但是我这也没跑超过8小时
导致这种问题的原因:
应用线程池还hold着数据库已经断掉的连接——“脏连接”
配置了validationQuery——select 1,但是查了下mysql的执行的全部log,根本执行该语句
调试下发现 usePingMethod为true
源码中usePingMethod为true ,就不会执行validateQuery部分
public boolean isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) throws Exception if (conn.isClosed()) return false; if (this.usePingMethod) if (conn instanceof DruidPooledConnection) conn = ((DruidPooledConnection) conn).getConnection(); if (conn instanceof ConnectionProxy) conn = ((ConnectionProxy) conn).getRawObject(); if (this.clazz.isAssignableFrom(conn.getClass())) if (validationQueryTimeout < 0) validationQueryTimeout = 1; try this.ping.invoke(conn, new Object[]Boolean.valueOf(true), Integer.valueOf(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 = "SELECT 1"; stmt = null; 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(禁止mysql connector自带的ping机制)
在jvm参数配置 -Ddruid.mysql.usePingMethod=false
附:
application.properties中的配置
## 数据库访问配置, 使用druid数据源 spring.datasource.druid.db-type=mysql spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.druid.url = jdbc:mysql://localhost:3306/bim?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false spring.datasource.druid.username=bimengine spring.datasource.druid.password=fgBQLZpgDaxH7xuu # 连接池配置 spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=20 # 配置获取连接等待超时的时间 spring.datasource.druid.max-wait=30000 spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.validation-query= select 1 spring.datasource.druid.validation-query-timeout=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.time-between-eviction-runs-millis=60000 # 打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-open-prepared-statements=20 spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall‘用于防火墙 spring.datasource.druid.filters=stat,wall # WebStatFilter配置 spring.datasource.druid.web-stat-filter.enabled=true spring.datasource.druid.web-stat-filter.url-pattern=/* spring.datasource.druid.web-stat-filter.exclusions=‘*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*‘ #是否启用StatFilter默认值true spring.datasource.druid.stat-view-servlet.enabled=true # 访问路径为/druid时,跳转到StatViewServlet spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* #druid监控管理界面登录帐号 spring.datasource.druid.stat-view-servlet.login-username=admin #druid监控管理界面登录密码 spring.datasource.druid.stat-view-servlet.login-password=admin@tydt spring.datasource.druid.stat-view-servlet.allow=127.0.0.1 # 配置StatFilter spring.datasource.druid.filter.stat.log-slow-sql=true
以上是关于Druid+mysql+mybatis做定时批量操作出现CommunicationsException: Communications link failure的主要内容,如果未能解决你的问题,请参考以下文章
SPRINGBOOT配置MYSQL,MYBATIS,DRUID
springboot+mybatis+Druid配置多数据源(mysql+postgre)
springboot整合mybatis+mysql+druid数据源
Spring boot + Mybatis + Thymeleaf + Druid +mySql