2023-07-24 21:54:41,754 ERROR com.alibaba.druid.pool.DruidPooledStatement
[] - CommunicationsException, druid version 1.2.8,
testWhileIdle true, idle millis 30042, minIdle 5, poolingCount 4,
timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 30042,
driver com.mysql.cj.jdbc.Driver,
exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter
2023-07-24 21:54:41,755 ERROR com.alibaba.druid.pool.DruidDataSource
[] - {conn-16455} discard
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
百度了很多,都说什么配置之类的,但是我是运行一段时间以后才会出问题的;
原因1、我设置的连接池最小的连接数是5,可用的是4个,有一个是被弃用的
2、连接池会一直保持最小连接数,认为里面都是可用的
3、从连接池中获取连接,取到的是哪个被弃用的,所以报错
我要的目的是让程序出问题的时候,能够继续运行下去,我从不要求程序运行一直不出问题,我要的是出了以问题以后能够继续运行!!!!
1、在从druid数据库连接池获取Connection的时候,try catch,若抛异常属于discard这种的,我就关闭连接池,重开连接池;
public Connection getConnection(JSONObject obj) {
Connection conn = null;
try {
conn = Sink.dataSource.getConnection();
} catch (Exception e) {
logger.error("druid连接池发生discard异常" e.getMessage());
Sink.dataSource.close();
Sink.dataSource = new Driud().getSource();
logger.error("dataSource 重新创建了");
}
return null;
}
return conn;
}
2、增大连接池最小连接池数,降低这种风险(从最小连接池里面取可用连接)
dataSource.setInitialSize(15);
dataSource.setMinIdle(15); //最小连接池数量
3、归还的时候,借出的时候都校验一下
dataSource.setTestWhileIdle(true); // <!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
比起性能,我觉得稳定性更重要
4、之前代码为了方便,增删改查都用一个链接Connection connection; 这样在并发情况下会泄露资源;代码不够健壮;
每个对数据库的操作都使用一个链接,操作数据库结束以后一个个个关闭
贴上我完整的连接池配置代码package Jdbc;
import com.alibaba.druid.pool.DruidDataSource;
public class Driud {
private static DruidDataSource dataSource = null;
public DruidDataSource getSource(){
dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://11.11.2.190:3306/jx_cloud_mes?serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useLegacyDatetimeCode=false");
dataSource.setUsername("root");
dataSource.setPassword("ems_2022");
dataSource.setInitialSize(15);
dataSource.setMinIdle(15); //最小连接池数量
dataSource.setMaxActive(30); //最大连接池数量
dataSource.setMaxWait(60000); //获取连接时最大等待时间,单位毫秒。配置了maxWait之后,
dataSource.setValidationQuery("select 1");
dataSource.setTestWhileIdle(true); // <!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTimeBetweenEvictionRunsMillis(60000); //有两个含义:1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
dataSource.setMinEvictableIdleTimeMillis(25200000); //<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
dataSource.setKeepAlive(true);
dataSource.setLogAbandoned(true);
dataSource.setRemoveAbandoned(true);
dataSource.setRemoveAbandonedTimeout(1800);
return dataSource;
}
}
突然发现try catch非常重要,一个程序运行几天可能没问题,但是运行很久,需要考虑各个方面。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved