Springboot1.5装载druid连接池的坑

springboot1.5使用DataSourceBuilder.build读取yml配置文件装载druid连接池的时候,期望对象是:com.alibaba.druid.pool.DruidDataSource,实际上装载的是:org.apache.tomcat.jdbc.pool.DataSource。

下面描述问题出现以及解决过程:
1.问题出现,程序正常运行一段时间不操作,之后再也无法继续操作数据库,经过分析,mysql主动断开连接时间interactive_timeout和wait_timeout设置的是1个小时,初步定位是mysql主动断开空闲连接之后,程序的连接池使用的仍然是旧的连接实例。

2.此时连接池的配置如下:
application.yml:

spring:
  application:
    name: archive
  datasource:
    mdb:
      type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://10.130.236.123:8066/mdb?useUnicode=true&characterEncoding=utf8
      username: mdb
      password: FASDSDJGJ782379482734==Xf34
      filters: stat 
      maxActive: 10
      initialSize: 1
      maxWait: 60000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 30000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false

java配置类:

	@Bean(name = "mdbDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mdb")
    @Primary
    public DataSource mdbDataSource() {
        DataSourceBuilder dsb = DataSourceBuilder.create();
        return dsb.build();
    }

这个配置预计效果是:每次从池中取连接时检查,如果连接空闲时间大于30秒,则通过select x校验该连接是否有效。
实际上并不起作用,druid并没有按预计效果执行。druid版本过低也无法达到此效果,不过本文非此问题。

3.druid提供了监控界面,但此时监控界面却打不开,开始怀疑druid实际没有启动,打印出数据源对象,发现竟然是org.apache.tomcat.jdbc.pool.DataSource的代理,此时自然想到了yml的配置属性:

type: com.alibaba.druid.pool.DruidDataSource

这行竟然没有指引DataSourceBuilder创建druid数据源。

4.网上铺天盖地的这种配置法,要么直接配置文件和jar包,让springboot自动装在,其实很多springboot2.x的配置,不适用与我们工程,我们springboot和springcloud,版本不高,完全按照网上做法,版本问题会导致springcloud无法使用。

5.无法,跟踪DruidDataSource.build的源码

	public DataSource build() {
		Class<? extends DataSource> type = getType();
		DataSource result = BeanUtils.instantiate(type);
		maybeGetDriverClassName();
		bind(result);
		return result;
	}

虽然springboot启动时,读取了配置,但是上文的type实际没有加载,使用默认值,最终解决方案是手动设置druid数据源,如下:

	@Bean(name = "mdbDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mdb")
    @Primary
    public DataSource mdbDataSource() {
        DataSourceBuilder dsb = DataSourceBuilder.create();
        // 手动设置数据源连接池类型
        DruidDataSource ds = new DruidDataSource();
        dsb.type(ds.getClass());
        return dsb.build();
    }

6.通过druid的监控,查看操作数据库的连接实例状况,发现1个小时内取出的都是同一个连接实例,超过1个小时空闲之后,再次操作,连接实例换掉,自此,问题解决。

你可能感兴趣的:(springcloud,springboot)