标签:read bool nic 操作 min discard str ons username
最近使用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
标签:read bool nic 操作 min discard str ons username
原文地址:https://www.cnblogs.com/baby123/p/11388048.html