Druid 1.1.24 在控制台打印"discard long time none received connection. , jdbcUrl : jdbc:mysql://...."错误日志
Druid 1.1.24 在控制台打印"discard long time none received connection. , jdbcUrl : jdbc:mysql://..."错误日志
参考资料
报错原因
- 我使用的是mysql 数据库,驱动包使用的是mysql-connector-java-8.0.27.jar
- druid 使用的是 druid-1.1.24.jar
- 经过每个包的翻看,在 com.alibaba.druid.pool.vendor 包下查到这个MySqlValidConnectionChecker类 ,根据类名猜测出这个是 MySQL 数据连接校验类.
- MySqlValidConnectionChecker 源码如下:
点击查看代码
public class MySqlValidConnectionChecker extends ValidConnectionCheckerAdapter implements ValidConnectionChecker, Serializable {
public static final int DEFAULT_VALIDATION_QUERY_TIMEOUT = 1;
public static final String DEFAULT_VALIDATION_QUERY = "SELECT 1";
private static final long serialVersionUID = 1L;
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
private Class<?> clazz;
private Method ping;
private boolean usePingMethod = false;
public MySqlValidConnectionChecker(){
try {
clazz = Utils.loadClass("com.mysql.jdbc.MySQLConnection");
if (clazz == null) {
clazz = Utils.loadClass("com.mysql.cj.jdbc.ConnectionImpl");
}
if (clazz != null) {
ping = clazz.getMethod("pingInternal", boolean.class, int.class);
}
if (ping != null) {
usePingMethod = true;
}
} catch (Exception e) {
LOG.warn("Cannot resolve com.mysql.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
}
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);
}
}
public boolean isUsePingMethod() {
return usePingMethod;
}
public void setUsePingMethod(boolean usePingMethod) {
this.usePingMethod = usePingMethod;
}
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);
}
}
}
- 根据源码中 isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) 方法,有个判断 :
// 如果使用 ping 方法,则会反射调用 ping 方法验证数据库连接是否有效,而不执行 validateQuery 验证.
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;
}
}
那么 usePingMethod 是怎么来的?
查看构造器方法:
public MySqlValidConnectionChecker(){
try {
// 先加载的驱动类
clazz = Utils.loadClass("com.mysql.jdbc.MySQLConnection");
if (clazz == null) {
clazz = Utils.loadClass("com.mysql.cj.jdbc.ConnectionImpl");
}
// 反射获取驱动类的 pingInternal 方法
if (clazz != null) {
ping = clazz.getMethod("pingInternal", boolean.class, int.class);
}
// 若驱动类的 pingInternal 方法如果存在则 usePingMethod = true
if (ping != null) {
usePingMethod = true;
}
} catch (Exception e) {
LOG.warn("Cannot resolve com.mysql.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
}
// 从系统配置文件配置属性,
configFromProperties(System.getProperties());
}
@Override
public void configFromProperties(Properties properties) {
// 从系统属性(JVM启动参数)中获取'druid.mysql.usePingMethod'属性 覆盖 usePingMethod 的值
String property = properties.getProperty("druid.mysql.usePingMethod");
if ("true".equals(property)) {
setUsePingMethod(true);
} else if ("false".equals(property)) {
setUsePingMethod(false);
}
}
以上可以得出结论, 通过配置JVM启动参数"druid.mysql.usePingMethod=false" 告知 Druid 停止使用 usePingMethod 方法验证数据库连接,转而使用 validateQuery 验证.
解决方法
1. JVM启动参数添加如下配置
-Ddruid.mysql.usePingMethod=false
Druid 1.1.24 在控制台打印"discard long time none received connection. , jdbcUrl : jdbc:mysql://...."错误日志的更多相关文章
- druid discard long time none received connection问题解析
最新项目中用的druid连接数据库遇到一个困扰很久的问题 1 开始用的druid版本是1.1.22版本,由于业务需求,单个连接需要执行很久,理论上不需要用到自动回收,但为了安全,还是加了自动回收,时间 ...
- Spring Boot 集成日志logback + 控制台打印SQL
一: 控制台打印SQL application.properties中添加如下即可在控制台打印sql logging.level.com.fx.fxxt.mapper=debug 二:日志 因为Spr ...
- 关于在Xcode控制台打印的注意点
注意!!在控制台中打印语句的返回值,这句代码也算是被执行过了一次 比如在下列代码的if语句执行之前,现在控制台打印 [_dataBaseexecuteUpdate:createSql] 的布尔值 if ...
- mybatis3.2.3+spring3 控制台打印sql解决办法
学习mybatis的时候遇到打印不出sql 的问题,在这里做个总结: 1:首先log4j.properties这样配置: log4j.rootLogger=DEBUG,console,R log4j. ...
- myeclipse 控制台打印空指针 ,黏贴控制台sql到plsql有结果集,异常处理
信用公司框架,不够熟悉. 在完成嗲点登录后,写动态页面是遇到,了问题:myeclipse 控制台打印空指针 ,黏贴控制台sql到plsql有结果集,异常处理. 最后大神给看,在接口实现重写的方法里返回 ...
- VS2010-win32下cocos2dx控制台打印的方法
在xcode中 直接使用printf 或者 cout<<""<<endl;可以直接在控制台打印 但是在VS2010 却死活不好用 真郁闷 ------ ...
- 控制台打印Hibernate的SQL语句显示绑定参数值
问题? 使用Hibernate提供的show_sql内置属性true只能输出类似于下面的SQL语句:Hibernate: insert into user(name,password) value ...
- node 在控制台打印有色彩的输出
在学习 node 过程中,因为没有找到有断点的调试方法,只能退而次之,在控制台打印调试. 但整个控制台的输出都是一种颜色,有时候很难找到自己需要的信息,这时,有颜色的打印就会帮上很大的忙. conso ...
- Spring Boot使用AOP在控制台打印请求、响应信息
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等. AOP简介 AOP全称Aspect Oriented Programming,面向切面,AOP主要实现的 ...
随机推荐
- MySQL CREATE TABLE 简单设计模板交流
推荐用 MySQL 8.0 (2018/4/19 发布, 开发者说同比 5.7 快 2 倍) 或同类型以上版本. CREATE TABLE TEMPLATE CREATE TABLE [table ...
- Sobel算子 Scharr算子 Laplacian算子
图像梯度处理 Sobel算子 水平方向: 对于线条A和线条B,右侧像素值与左侧像素值的差值不为零,因此是边界 上下像素值差值为0,左右素值的差值不为零,分布为正负, 离的近的为2,离的远的为1 P5= ...
- 程序语言与编程实践7-> Java实操4 | 第三周作业及思路讲解 | 异常处理考察
第三周作业,可能是异常那一章当时没怎么听,此前也不怎么接触,感觉还挺陌生的. 00 第1题 00-1 题目 /* * To change this license header, choose Lic ...
- 什么是Spring的依赖注入?
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释.这概念是说你不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个 ...
- 什么是原子操作?在 Java Concurrency API 中有哪些原 子类(atomic classes)?
原子操作(atomic operation)意为"不可被中断的一个或一系列操作" . 处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作. 在 Java 中可以通 ...
- 构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载.
- Java的HashMap是如何工作的?
HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap 基于 hashing 原理,我们通过 put ()和 get ()方法储存和获取对象.当我们将键值对 ...
- Oracle入门基础(九)一一创建表和管理表
练习:查询每一年入职人数及总人数 SQL> select count(*) Total, 2 sum(decode(to_char(hiredate,'yyyy'),'1980',1,0)) & ...
- MyISAM 表格将在哪里存储,并且还提供其存储格式?
每个 MyISAM 表格以三种格式存储在磁盘上: ·".frm"文件存储表定义 ·数据文件具有".MYD"(MYData)扩展名 索引文件具有".MY ...
- Java中自动装箱与拆箱
一.什么是封装类? Java中存在基础数据类型,但是在某些情况下,我们要对基础数据类型进行对象的操作,例如,集合中只能存在对象,而不能存在基础数据类型,于是便出现了包装器类.包装器类型就是对基本数据类 ...