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 对象监控。

相关推荐
ByteBlossom3 分钟前
MySQL 面试场景题之如何处理 BLOB 和CLOB 数据类型?
数据库·mysql·面试
麦兜*9 分钟前
MongoDB Atlas 云数据库实战:从零搭建全球多节点集群
java·数据库·spring boot·mongodb·spring·spring cloud
Slaughter信仰12 分钟前
深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十章知识点问答(10题)
java·jvm·数据库
麦兜*14 分钟前
MongoDB 在物联网(IoT)中的应用:海量时序数据处理方案
java·数据库·spring boot·物联网·mongodb·spring
汤姆yu16 分钟前
基于springboot的毕业旅游一站式定制系统
spring boot·后端·旅游
-Xie-1 小时前
Mysql杂志(十六)——缓存池
数据库·mysql·缓存
七夜zippoe1 小时前
缓存与数据库一致性实战手册:从故障修复到架构演进
数据库·缓存·架构
沐矢羽1 小时前
Tomcat PUT方法任意写文件漏洞学习
学习·tomcat
计算机毕业设计木哥1 小时前
计算机毕设选题推荐:基于Java+SpringBoot物品租赁管理系统【源码+文档+调试】
java·vue.js·spring boot·mysql·spark·毕业设计·课程设计