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

相关推荐
m0_748256785 分钟前
SpringBoot 依赖之Spring Web
前端·spring boot·spring
猿来入此小猿10 分钟前
基于SpringBoot在线音乐系统平台功能实现十二
java·spring boot·后端·毕业设计·音乐系统·音乐平台·毕业源码
愤怒的代码23 分钟前
Spring Boot对访问密钥加解密——HMAC-SHA256
java·spring boot·后端
Ahern_27 分钟前
Oracle 普通表至分区表的分区交换
大数据·数据库·sql·oracle
栗豆包39 分钟前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven
夜半被帅醒1 小时前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
万亿少女的梦1681 小时前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
不爱学习的啊Biao1 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
破 风1 小时前
SpringBoot 集成 MongoDB
数据库·mongodb
Rverdoser1 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql