Druid连接池参数maxWait配置错误引发的问题

Druid连接池参数maxWait配置错误引发的问题

1. 背景

数据库服务器(服务部署在客户内网环境)的运行一段时间后,网卡出现了问题,导致所有服务都连接不上数据库,客户把网络恢复之后,反馈有个服务还是访问异常。

2.问题定位

查看异常服务的日志,发现当时的日志打印出了大量的Too many open files,日志表明当时该进程打开的文件句柄数已达到上限,该进程已经不能自动恢复对数据库的访问。

Druid连接池参数maxWait配置错误引发的问题

通过命令ulimit -a查看配置,确认服务器配置没有问题。

Druid连接池参数maxWait配置错误引发的问题

使用jstack命令查看当时线程的信息,发现大量获取数据库连接的线程处于BLOCKED状态。

Druid连接池参数maxWait配置错误引发的问题

从线程堆栈信息发现,线程是从Druid连接池获取连接的,于是查看DruidDataSource获取连接的方法,发现有个maxWait参数(默认配置为-1)

Druid连接池参数maxWait配置错误引发的问题

查看项目的配置文件,发现有配置spring.datasource.maxWait=60000

Druid连接池参数maxWait配置错误引发的问题

通过debug的方式发现改配置没有生效

Druid连接池参数maxWait配置错误引发的问题

3.原因分析

项目是通过spring.datasource.type=com.alibaba.druid.pool.DruidDataSource引入druid连接池,通过这种方式引入配置文件中的其他属性是无法自动注入。要使该配置生效,可使用javaBean的方式配置。

@Configuration
public class DruidConfig {

    @Bean
    // 将所有前缀为spring.datasource下的配置项都加载DataSource中
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

}

关于maxWait的默认值,即如果连接池没有空闲连接,获取连接的线程则会一直等待下去。在项目中,在后台有个按时触发统计的定时任务,定时的向连接池获取连接,即每个固定时间间隔内就会有一个线程阻塞。数据库宕机时间一长就会导致,该进程打开的句柄数超过上限。

关于spring.datasource前缀没有自动注入的原因,可以自行查看springboot 数据源自动注入DataSourceAutoConfiguration类

上一篇:Springboot整合Mybatis,连接多个数据库(Mysql+Oracle)


下一篇:Eclipse离线安装Java Decompiler插件