Springboot_Tomcat数据库连接池配置

Springboot_Tomcat数据库连接池配置

一、环境

  • jdk 1.8
  • springboot 1.56

二、连接池使用的配置类

  • 包名:tomcat-jdbc-8.5.16.jar
  • 类名:org.apache.tomcat.jdbc.pool.PoolProperties

配置在yaml中的内容将转换为该类型,类中的默认值即为连接池的默认配置。

三、Tomcat JDBC 连接池属性及默认值

属性 描述 默认值
defaultAutoCommit 连接池中创建的连接默认是否自动提交事务 驱动的缺省值
defaultReadOnly 连接池中创建的连接默认是否为只读状态 -
defaultCatalog 连接池中创建的连接默认的 catalog -
driverClassName 驱动类的名称 -
username 数据库账户 -
password 数据库密码 -
maxActive 连接池同一时间可分配的最大活跃连接数 100
maxIdle 始终保留在池中的最大连接数,如果启用,将定期检查限制连接,超出此属性设定的值且空闲时间超过minEvictableIdleTimeMillis的连接则释放 与maxActive设定的值相同
minIdle 始终保留在池中的最小连接数,池中的连接数量若低于此值则创建新的连接,如果连接验证失败将缩小至此值 与initialSize设定的值相同
initialSize 连接池启动时创建的初始连接数量 10
maxWait 最大等待时间(毫秒),如果在没有连接可用的情况下等待超过此时间,则抛出异常 30000(30秒)
testOnBorrow 当从连接池中取出一个连接时是否进行验证,若验证失败则从池中删除该连接并尝试取出另一个连接 false
testOnConnect 当一个连接首次被创建时是否进行验证,若验证失败则抛出 SQLException 异常 false
testOnReturn 当一个连接使用完归还到连接池时是否进行验证 false
testWhileIdle 对池中空闲的连接是否进行验证,验证失败则回收此连接 false
validationQuery 在连接池返回连接给调用者前用来对连接进行验证的查询 SQL null
validationQueryTimeout SQL 查询验证超时时间(秒),小于或等于 0 的数值表示禁用 -1
timeBetweenEvictionRunsMillis 在空闲连接回收器线程运行期间休眠时间(毫秒), 该值不应该小于 1 秒,它决定线程多久验证空闲连接或丢弃连接的频率 5000(5秒)
minEvictableIdleTimeMillis 连接在池中保持空闲而不被回收的最小时间(毫秒) 60000(60秒)
removeAbandoned 标记是否删除泄露的连接,如果连接超出removeAbandonedTimeout的限制,且该属性设置为 true,则连接被认为是被泄露并且可以被删除 false
removeAbandonedTimeout 泄露的连接可以被删除的超时时间(秒),该值应设置为应用程序查询可能执行的最长时间 60

四、ymal配置tomcat数据库连接池示例

创建连接开销比较大,尤其是频繁创建和销毁连接对象时会带来性能损耗,使用连接池的可以有效利用资源避免开销,提升查询性能。

连接池参数设置尤为重要,其中maxActive为设置时需要考虑集群实例数去分配,一般数据库支持的连接数最大1500左右(也需要开看服务器的配置)。

由于网络不稳或者db服务器重启,导致的连接断开的情况,可以设置testOnReturn、testWhileIdle参数在连接出入池时进行有效性校验,无效连接将从池子中清理。

复制代码
spring:
  datasource:
    url: jdbc:postgresql://localhost:12306/mydb?currentSchema=myschema
    username: pguser
    password: ******
    #默认连接池
    initialSize: 1  #池启动时打开的连接数
    maxActive: 20    #打开的最大连接数
    maxIdle: 5      #最大空闲连接数
    minIdle: 5      #打开连接的最小数量
    maxWait: 60000  #获取连接时抛出SQLException之前等待的时间(以毫秒为单位)
    testOnBorrow: false   #如池中借出对象之前验证,如果对象验证失败,将其从池中清除,再接着去借下一个。
    testOnReturn: true    #连接返回池之前进行验证,则为True
    testWhileIdle: true   #连接空闲时进行验证,如果验证失败则将其从池中清除。
    timeBetweenEvictionRunsMillis: 60000  #间隔检测毫秒数
    minEvictableIdleTimeMillis: 300000  #连接最小生存毫秒数
    validationQueryTimeout: 30    #验证查询超时秒数
    validationQuery: select 1 AS count    #检测连接是否有效的SQL

五、验证配置的参数是否生效

配置完连接池完全是黑盒,配置的参数是否生效?连接池当前的状态怎样?我们怎么监控?

通过下面的方法可以获取到连接池的状态和参数,逻辑是通过注入的方式获得到SqlSessionFactory对象,

在org.apache.tomcat.jdbc.pool.DataSource对象中获取连接池的实时状态。

复制代码
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactories;

    public List<Map<String,Object>> tomcatConnectionPoolMonitor() {
        List<Map<String,Object>> rst = new ArrayList<>();
        sqlSessionFactories.forEach(factory->{
            Map<String,Object> m = new HashMap<>();
            Configuration config = factory.getConfiguration();
            DataSource dataSource = config.getEnvironment().getDataSource();
            if(dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource){
                org.apache.tomcat.jdbc.pool.DataSource poolDs
                        = (org.apache.tomcat.jdbc.pool.DataSource)dataSource;
                ConnectionPool  pool = poolDs.getPool();
                PoolConfiguration pConf = poolDs.getPoolProperties();
                Properties db = pConf.getDbProperties();
                String srt = ToStringBuilder.reflectionToString(pConf);
                //数据源
                m.put("dataSource.type",poolDs.getClass().getName());
                //连接池状态
                m.put("pool.name",pool.getName());
                m.put("pool.hashCode",pool.hashCode());
                m.put("pool.ver",pool.getPoolVersion());
                m.put("pool.size",pool.getSize());
                m.put("pool.active",pool.getActive());
                m.put("pool.idle",pool.getIdle());
                m.put("pool.createdCount",pool.getCreatedCount());
                m.put("pool.releasedCount",pool.getReleasedCount());
                m.put("pool.returnedCount",pool.getReturnedCount());
                m.put("pool.reconnectedCount",pool.getReconnectedCount());
                m.put("pool.removeAbandonedCount",pool.getRemoveAbandonedCount());
                m.put("pool.releasedIdleCount",pool.getReleasedIdleCount());
                //连接池属性
                m.put("conf.hashCode",pConf.hashCode());
                m.put("conf.name",pConf.getName());
                m.put("conf.user",pConf.getUsername());
                m.put("conf.url",pConf.getUrl());
                m.put("conf.initialSize",pConf.getInitialSize());    //池启动时打开的连接数
                m.put("conf.maxActive",pConf.getMaxActive());        //打开的最大连接数
                m.put("conf.maxIdle",pConf.getMaxIdle());    //最大空闲连接数
                m.put("conf.minIdle",pConf.getMinIdle());    //打开连接的最小数量
                m.put("conf.maxWait",pConf.getMaxWait());    //获取连接时抛出SQLException之前等待的时间(以毫秒为单位)
                m.put("conf.testOnBorrow",pConf.isTestOnBorrow());   //获取连接之前验证,如果对象验证失败,则从池中清除
                m.put("conf.testOnReturn",pConf.isTestOnReturn());   //连接返回池之前进行验证,则为True
                m.put("conf.testWhileIdle",pConf.isTestWhileIdle()); //连接空闲时进行验证,如果验证失败则将其从池中清除。
                m.put("conf.timeBetweenEvictionRunsMillis",pConf.getTimeBetweenEvictionRunsMillis());//间隔毫秒
                m.put("conf.minEvictableIdleTimeMillis",pConf.getMinEvictableIdleTimeMillis());//最小空闲时间ms
                m.put("conf.validationQueryTimeout",pConf.getValidationQueryTimeout());//超时时间(ms)
                m.put("conf.validationQuery",pConf.getValidationQuery());    //检测连接是否有效的SQL
            }else{
                m.put("dataSource.type",dataSource.getClass().getName());
            }
            rst.add(m);
        });
        return rst;
    }

六、返回的验证结果

复制代码
[
    {
        "conf.hashCode": -107389976,
        "conf.initialSize": 1,
        "conf.maxActive": 20,
        "conf.maxIdle": 5
        "conf.maxWait": 60000,
        "conf.minEvictableIdleTimeMillis": 300000,
        "conf.minIdle": 5,
        "conf.name": "Tomcat Connection Pool[1--586968016]",
        "conf.testOnBorrow": false,
        "conf.testOnReturn": true,
        "conf.testWhileIdle": true,
        "conf.timeBetweenEvictionRunsMillis": 60000,
        "conf.url": "jdbc:postgresql://localhost:12306/mydb?currentSchema=myschema",
        "conf.user": "pguser",
        "conf.validationQuery": "select 1 AS count",
        "conf.validationQueryTimeout": 30,
        "dataSource.type": "org.apache.tomcat.jdbc.pool.DataSource",
        "pool.active": 0,
        "pool.createdCount": 1,
        "pool.hashCode": 885141032,
        "pool.idle": 1,
        "pool.name": "Tomcat Connection Pool[1--586968016]",
        "pool.reconnectedCount": 0,
        "pool.releasedCount": 0,
        "pool.releasedIdleCount": 0,
        "pool.removeAbandonedCount": 0,
        "pool.returnedCount": 13,
        "pool.size": 1,
        "pool.ver": -9223372036854775808,
    }
]

总结

springboot 1.5x 默认使用 tomcat 连接池,配置后是否生效可以通过 org.apache.tomcat.jdbc.pool.DataSource 对象监控。

相关推荐
上官浩仁2 小时前
springboot synchronized 本地锁入门与实战
java·spring boot·spring
树谷-胡老师3 小时前
公元前3400年至公元2024年全球国家地理边界演变数据集
数据库·arcgis·信息可视化
疯狂的Alex3 小时前
2010-2022 同等学力申硕国考:软件工程简答题真题汇总
数据库·oracle·软件工程
m0_748461393 小时前
Spring Boot + Vue 项目中使用 Redis 分布式锁案例
vue.js·spring boot·redis
山东小木3 小时前
JBoltAI需求分析大师:基于SpringBoot的大模型智能需求文档生成解决方案
人工智能·spring boot·后端·需求分析·jboltai·javaai·aigs
Qlittleboy3 小时前
tp5的tbmember表闭包查询 openid=‘abc‘ 并且(wx_unionid=null或者wx_unionid=‘‘)
数据库·sql·php
躲在云朵里`3 小时前
Spring Scheduler定时任务实战:从零掌握任务调度
java·数据库·mybatis
小白不想白a3 小时前
【MySQL】常用SQL语句
数据库·sql·mysql
RestCloud4 小时前
从MySQL到StarRocks:全量与增量同步的最佳实践
数据库·mysql·api
Databend4 小时前
Databend 八月月报:向量检索重磅上线,性能飞跃几十倍
数据库