先上配置文件
在这里插入图片描述

主yml配置文件

spring:
  datasource:
    driver-class-name: ${db-driver}
    url: ${db-url}
    username: ${db-username}
    password: ${db-password}
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      stat-view-servlet.enabled: false
      initialSize: 5
      minIdle: 5
      maxActive: 15
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20

local配置文件

#数据库连接信息
db-driver: com.mysql.cj.jdbc.Driver
db-url: jdbc:mysql://127.0.0.1:13306/report?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowMultiQueries=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
db-username: root
db-password: '123456abcd'

现象说明,项目启动耗时9秒,接着调用某个接口(第一次调用),控制台出现数据库初始化日志,并且查询耗时16秒,同样的接口,同样的参数,接着调用第二次,第二次没有DruidDataSource - {dataSource-1} inited的日志出现,并且,并且耗时0.015秒。
在这里插入图片描述
也就是说,这个项目的连接池初始化用了16秒。看了很多人解决方案说,让项目启动的时候,进行初始化,不过那样项目启动就会变得很慢了,所以还是决定,花点时间,看看能不能解决这个问题。

写个简单点的代码进行测试

public class DBInitTest {
    public static void main(String[] args) throws SQLException {
        long start = System.currentTimeMillis();
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://127.0.0.1:13306/report?serverTimezone=Asia/Shanghai&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("123456abcd");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setInitialSize(5); // 与项目配置一致
        dataSource.init(); // 手动触发初始化
        System.out.println("初始化耗时:" + (System.currentTimeMillis() - start) + "ms");
        dataSource.close();
    }
}

这下更离谱,初始化时间居然花了接近80秒。

11:29:35.584 [main] INFO com.alibaba.druid.pool.DruidDataSource -- {dataSource-1} inited
初始化耗时:78505ms
11:29:35.586 [main] INFO com.alibaba.druid.pool.DruidDataSource -- {dataSource-1} closing ...
11:29:35.594 [main] INFO com.alibaba.druid.pool.DruidDataSource -- {dataSource-1} closed
11:30:53.591 [main] INFO com.alibaba.druid.pool.DruidDataSource -- {dataSource-2} inited

将dataSource.setInitialSize();改为1后,时间来到16秒,此时时间就和配置文件配置时,初始化的时间一样了,都是16秒,至于为啥会这样,我觉得大概可能是,配置文件创建的连接,第二个连接创建的时候复用了第一次创建的某些资源,然后就配置5个连接,也还是16秒,自己编写的测试初始化,可能第二次,第三次都不会复用第一次的资源,而是完全从新创建,也就是16 x 5 = 80秒。和上面的好像能匹配上。
在这里插入图片描述
现在问题定位出来了,就是连接池初始化的时候时间太长。理论上初始化时不需要这么多时间的。

同样的代码配置在以前SpringBoot2.x以前是没问题的(也说明,我见证SpringBoot从1.5到2.7),然后现在是升级到SpringBoot3.4了。出现了这个第一次初始化很长时间的问题。

通过我项目中看到的mysql依赖,可以发现,驱动是9.1版本。
在这里插入图片描述
查看以前旧版的代码,发现版本是8.0.23
在这里插入图片描述
SpringBoot3.4里面,没有8.0.23,这里我使用8.0.33版本
在这里插入图片描述
如下所示,现在可以看到,即使第一次查询在进行初始化,时间也在一秒以内。
在这里插入图片描述

Logo

一站式 AI 云服务平台

更多推荐