
spring:
datasource:
dynamic:
primary: master
strict: false
druid:
filters: stat
initialSize: 5
minIdle: 5
maxActive: 50
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
validationQuery: SELECT 1
removeAbandoned: true
removeAbandonedTimeoutMillis: 300000
logAbandoned: true当数据后宕机后,服务报以下错误,数据库连接池背关闭,即使数据库恢复后,服务也无法恢复,需要重启服务
2025-10-31 19:14:43 xxx-xxx-xxx ERROR Druid-ConnectionPool-Create-1973861638 com.alibaba.druid.pool.DruidDataSource [DruidDataSource.java:2969] create conne
ction Exception, url: jdbc:mysql://xxx.xxx.xxx:3306/db?characterEncoding=utf-8&allowMultiQueries=true&connectTimeout=60000&socketTimeout=3000
00&autoReconnect=true&useSSL=false, errorCode 0, state 08001
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Fri Oct 31 19:14:43 CST 2025问题在于 com.mysql.jdbc.ConnectionImpl#connectWithRetries,默认在未配置重试次数和间隔的时候,最多重试3次,每次间隔2s,将不会再进行重试
private void connectWithRetries(boolean isForReconnect, Properties mergedProps) throws SQLException {
double timeout = getInitialTimeout();
boolean connectionGood = false;
Exception connectionException = null;
for (int attemptCount = 0; (attemptCount < getMaxReconnects()) && !connectionGood; attemptCount++) {
try {
if (this.io != null) {
this.io.forceClose();
}
coreConnect(mergedProps);
pingInternal(false, 0);
boolean oldAutoCommit;
int oldIsolationLevel;
boolean oldReadOnly;
String oldCatalog;
synchronized (getConnectionMutex()) {
this.connectionId = this.io.getThreadId();
this.isClosed = false;
// save state from old connection
oldAutoCommit = getAutoCommit();
oldIsolationLevel = this.isolationLevel;
oldReadOnly = isReadOnly(false);
oldCatalog = getCatalog();
this.io.setStatementInterceptors(this.statementInterceptors);
}
// Server properties might be different from previous connection, so initialize again...
initializePropsFromServer();
if (isForReconnect) {
// Restore state from old connection
setAutoCommit(oldAutoCommit);
if (this.hasIsolationLevels) {
setTransactionIsolation(oldIsolationLevel);
}
setCatalog(oldCatalog);
setReadOnly(oldReadOnly);
}
connectionGood = true;
break;
} catch (Exception EEE) {
connectionException = EEE;
connectionGood = false;
}
if (connectionGood) {
break;
}
if (attemptCount > 0) {
try {
Thread.sleep((long) timeout * 1000);
} catch (InterruptedException IE) {
// ignore
}
}
} // end attempts for a single host
if (!connectionGood) {
// We've really failed!
SQLException chainedEx = SQLError.createSQLException(
Messages.getString("Connection.UnableToConnectWithRetries", new Object[] { Integer.valueOf(getMaxReconnects()) }),
SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor());
chainedEx.initCause(connectionException);
throw chainedEx;
}
if (getParanoid() && !getHighAvailability()) {
this.password = null;
this.user = null;
}
if (isForReconnect) {
//
// Retrieve any 'lost' prepared statements if re-connecting
//
Iterator<Statement> statementIter = this.openStatements.iterator();
//
// We build a list of these outside the map of open statements, because in the process of re-preparing, we might end up having to close a prepared
// statement, thus removing it from the map, and generating a ConcurrentModificationException
//
Stack<Statement> serverPreparedStatements = null;
while (statementIter.hasNext()) {
Statement statementObj = statementIter.next();
if (statementObj instanceof ServerPreparedStatement) {
if (serverPreparedStatements == null) {
serverPreparedStatements = new Stack<Statement>();
}
serverPreparedStatements.add(statementObj);
}
}
if (serverPreparedStatements != null) {
while (!serverPreparedStatements.isEmpty()) {
((ServerPreparedStatement) serverPreparedStatements.pop()).rePrepare();
}
}
}
}调整参数
spring:
datasource:
dynamic:
primary: master
strict: false
druid:
filters: stat
initialSize: 5
minIdle: 5
maxActive: 50
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
validationQuery: SELECT 1
removeAbandoned: true
removeAbandonedTimeoutMillis: 300000
logAbandoned: true
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://xxx.xxx.xxx:3306/orca?characterEncoding=utf-8&allowMultiQueries=true&connectTimeout=60000&socketTimeout=300000&autoReconnect=true&useSSL=false&maxReconnects=6000&initialTimeout=10原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。