druid 获取数据库连接失败,一直wait.DruidDataSource.takeLast
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000780199268> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:1448)
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1090)
问题:
高并发场景,Druid获取数据库连接一直等待,获取不了数据库链接;
解决办法:
-
先确保 spring.datasource.maxWait 不为 -1, -1表示永久等待, 可以配置为6000, 参考配置
-
没有采用druid starter的情况下, 可以试下在代码中手动配置 DataSource; 实测有效
@Slf4j
@Configuration
public class DruidConfig {
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.druid.username:admin}")
private String druidUsername;
@Value("${spring.datasource.druid.password:hd123}")
private String druidPassword;
@Value("${spring.datasource.driver-class-name:com.mysql.jdbc.Driver}")
private String driverClassName;
@Value("${spring.datasource.initialSize:10}")
private int initialSize;
@Value("${spring.datasource.minIdle:10}")
private int minIdle;
@Value("${spring.datasource.maxActive:1000}")
private int maxActive;
@Value("${spring.datasource.maxWait:-1}")
private int maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis:60000}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis:1800000}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery:SELECT 1}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle:true}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow:false}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn:false}")
private boolean testOnReturn;
@Value("${spring.datasource.poolPreparedStatements:true}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.filters:stat,log4j}")
private String filters;
@Value("${spring.datasource.logSlowSql:true}")
private String logSlowSql;
public DruidConfig() {
}
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings(new String[]{"/druid/*"});
reg.addInitParameter("loginUsername", this.druidUsername);
reg.addInitParameter("loginPassword", this.druidPassword);
reg.addInitParameter("logSlowSql", this.logSlowSql);
return reg;
}
@Bean
@Primary
public DataSource druidDataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(this.username);
datasource.setPassword(this.password);
datasource.setDriverClassName(this.driverClassName);
datasource.setInitialSize(this.initialSize);
datasource.setMinIdle(this.minIdle);
datasource.setMaxActive(this.maxActive);
datasource.setMaxWait(this.maxWait);
datasource.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);
datasource.setValidationQuery(this.validationQuery);
datasource.setTestWhileIdle(this.testWhileIdle);
datasource.setTestOnBorrow(this.testOnBorrow);
datasource.setTestOnReturn(this.testOnReturn);
datasource.setPoolPreparedStatements(this.poolPreparedStatements);
datasource.setConnectionInitSqls(Collections.singletonList("set names utf8mb4"));
try {
datasource.setFilters(this.filters);
} catch (SQLException var3) {
log.error("druid configuration initialization filter", var3);
}
return datasource;
}
}