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

相关推荐
猴子请来的逗比48914 分钟前
tomcat与nginx之间实现多级代理
java·nginx·tomcat
清幽竹客25 分钟前
redis数据结构-09 (ZADD、ZRANGE、ZRANK)
数据结构·数据库·redis
A~taoker30 分钟前
django扩展练习记录
数据库·django·sqlite
I_itaiit36 分钟前
Spring Boot之Web服务器的启动流程分析
spring boot·nettywebserver·httphandler·webhandler
敲上瘾1 小时前
MySQL数据库表的约束
linux·数据库·sql·mysql·数据库开发·数据库架构·数据库系统
努力的搬砖人.1 小时前
SQLite 转换为 MySQL 数据库
数据库·mysql·sqlite
2301_803297752 小时前
Shell编程值正则表达式和文本处理器
数据库·mysql·正则表达式
老李不敲代码2 小时前
榕壹云搭子系统技术解析:基于Spring Boot+MySQL+UniApp的同城社交平台开发实践
spring boot·mysql·微信小程序·uni-app·软件需求
com未来2 小时前
使用 NSSM 安装 Tomcat 11.0.6 为 Windows 服务
java·windows·tomcat
TDengine (老段)3 小时前
基于 TSBS 标准数据集下 TimescaleDB、InfluxDB 与 TDengine 性能对比测试报告
java·大数据·开发语言·数据库·时序数据库·tdengine·iotdb