美文网首页HiKariCP
记hikariCP-动态数据源切换线程池未生效的小坑

记hikariCP-动态数据源切换线程池未生效的小坑

作者: baiyin1115 | 来源:发表于2018-10-11 10:19 被阅读0次

    最近将项目进行压测发现系统巨慢,调查发现是数据库连接池的问题,可是修改数据库连接池参数后参数没有生效,很奇怪,查询代码后,发现问题如下:

    当前项目的动态数据源切换前任哥们copy了网上的例子。个人搜索了下,例子的地址如下:

    https://blog.csdn.net/catoop/article/details/50575038#comments

    我这个前任哥们儿copy过来以后,我感觉他应该是发现最近市场上比较流行hikariCP这个号称史上最快的数据源,顺便也给引入了。最后的配置信息如下:

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/XXX?useUnicode=true&characterEncoding=GBK
        username: XXXX
        password: XXXXXXX
        driver-class-name: com.mysql.jdbc.Driver
        hikari:
          connection-test-query: SELECT 1 FROM DUAL
          minimum-idle: 1
          maximum-pool-size: 5
          pool-name: bosPoolName
          max-lifetime: 1800000
    
        secondary:
          url: jdbc:mysql://127.0.0.1:3306/XXX?useUnicode=true&characterEncoding=GBK
          username: XXX
          password: XXX
          driver-class-name: com.mysql.jdbc.Driver
          hikari:
            connection-test-query: SELECT 1 FROM DUAL
            minimum-idle: 1
            maximum-pool-size: 5
            pool-name: bosPoolName
            max-lifetime: 1800000
    

    大致这意思哈,原来咋写的懒得找了。。。。反正是按照springboot官方给定的配置编写的,运行起来也没啥问题,但是我们的动态数据源设置方式并不是按照spring官方给的方式去设置的,压测的时候数据库连接池并没有生效,并发一上来,完犊子。

    因为copy例子里面数据源配置的核心代码如下:

    /**
         * 为DataSource绑定更多数据
         *
         * @param dataSource
         * @param env
         * @author SHANHY
         * @create  2016年1月25日
         */    
    private void dataBinder(DataSource dataSource, Environment env){
            RelaxedDataBinder dataBinder = new RelaxedDataBinder(dataSource);
            //dataBinder.setValidator(new LocalValidatorFactory().run(this.applicationContext));
            dataBinder.setConversionService(conversionService);
            dataBinder.setIgnoreNestedProperties(false);//false
            dataBinder.setIgnoreInvalidFields(false);//false
            dataBinder.setIgnoreUnknownFields(true);//true
            if(dataSourcePropertyValues == null){
                Map<String, Object> rpr = new RelaxedPropertyResolver(env, "spring.datasource").getSubProperties(".");
                Map<String, Object> values = new HashMap<>(rpr);
                // 排除已经设置的属性
                values.remove("type");
                values.remove("driver-class-name");
                values.remove("url");
                values.remove("username");
                values.remove("password");
                dataSourcePropertyValues = new MutablePropertyValues(values);
            }
            dataBinder.bind(dataSourcePropertyValues);
        }
    

    上面的代码就是参数绑定,本质上是将配置文件minimum-idle、maximum-pool-size这样的参数信息赋值给com.zaxxer.hikari.HikariConfig的配置变量,HikariConfig变量定义如下:

       private volatile String catalog;
       private volatile long connectionTimeout;
       private volatile long validationTimeout;
       private volatile long idleTimeout;
       private volatile long leakDetectionThreshold;
       private volatile long maxLifetime;
       private volatile int maxPoolSize;
       private volatile int minIdle;
       private volatile String username;
       private volatile String password;
    

    这里就有问题了,springboot默认的hikari参数都是以“-”进行分隔的,在赋值过程中应该进行了转义,我们自己写的这个并没有干这个事情,所以所有的配置信息并未生效,我们用的还是hikari的默认配置信息,所以压测出了问题。最后我们将配置文件修改如下:

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/XXX?useUnicode=true&characterEncoding=GBK
        username: XXXX
        password: XXXXXXX
        driver-class-name: com.mysql.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        poolName: bosPoolName
        minimumIdle: 5
        maximumPoolSize: 20
        connectionTimeout: 60000
        cachePrepStmts: true
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
    
        secondary:
          url: jdbc:mysql://127.0.0.1:3306/XXX?useUnicode=true&characterEncoding=GBK
          username: XXX
          password: XXX
          driver-class-name: com.mysql.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource
          poolName: bosPoolName2
          minimumIdle: 5
          maximumPoolSize: 20
          connectionTimeout: 60000
    

    解决了这个问题。

    其实问题很小,只要引入的时候细心一点、怀疑一下就能发现,千万别想当然的接进去,系统启动了,好好,搞定。
    后面填坑的人并不知道你老人家当时是怎么想的,排查的时候痛苦的一逼啊。

    相关文章

      网友评论

        本文标题:记hikariCP-动态数据源切换线程池未生效的小坑

        本文链接:https://www.haomeiwen.com/subject/jhnvaftx.html