postgreSql最佳配置详解(connection 申请、回收策略)
一、引子
合理配置一个应用的数据库参数,使其运行良好,这很重要。本文以某务中台的生产环境为例,从Apollo上拔下来一套配置,分析是否合理。
二、MybatisPlus配置
由于我们使用Apollo配置参数,所以分两部分:1.个体配置 2.全局配置
2.1 mybatisplus个体配置
mybatis-plus.mapper-locations = classpath*:/mapper/*Mapper.xml mapper文件地址匹配
mybatis-plus.type-aliases-package =xx.po 映射的实体包路径,
mybatis-plus.tenant-config.ignoretable = table1,table2
mybatis-plus.auth-config = []
mybatis-plus.global-config.sql-parser-cache = true 缓存sql解析
2.2 mybatis-plus全局配置
mybatis-plus.mapper-locations = classpath:/mapper/*Mapper.xml mapper文件地址匹配
mybatis-plus.configuration.map-underscore-to-camel-case = true 下划线转驼峰
mybatis-plus.global-config.logic-delete-value = true 逻辑已删除值
mybatis-plus.global-config.logic-not-delete-value = false 逻辑未删除值
mybatis-plus.max-query-records-size = 10000
三、Datasource配置
3.1 dataSource个体配置
=========数据库配置=========
spring.datasource.connectionProperties = druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 通过connectProperties属性来打开mergeSql功能;慢SQL记录5秒
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource 使用德鲁伊连接池
spring.datasource.driver-class-name = org.postgresql.Driver 驱动类名
spring.datasource.url = xx 数据库连接url
spring.datasource.username = ${dbUserName} 用户名
spring.datasource.password = ${dbPassword} 密码
spring.datasource.minIdle = 5 最小空闲连接数 5
spring.datasource.initialSize = 5 初始连接数 5
spring.datasource.maxActive = 100 最大连接数
spring.datasource.maxWait = 60000 获取连接等待超时的时间 60s=1分钟
spring.datasource.filters = stat,wall 监控统计拦截,用于监控界面sql统计
spring.datasource.poolPreparedStatements = false 是否启用缓存PreparedStatements
spring.datasource.maxPoolPreparedStatementPerConnectionSize = 20 指定每个连接上preStatement缓存数---》未生效!!!
=========健康检查=========
spring.datasource.validationQuery = SELECT 1 连接池的健康检查SQL
spring.datasource.testOnBorrow = false 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
spring.datasource.testOnReturn = false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
spring.datasource.testWhileIdle = true 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
#每timeBetweenEvictionRunsMillis毫秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止
spring.datasource.minEvictableIdleTimeMillis = 300000 最小可驱逐空闲时间,连接保持空闲而不被驱逐的最长时间,单位是毫秒 300s=5分钟
spring.datasource.timeBetweenEvictionRunsMillis = 60000 间隔多久才进行一次驱逐检测,单位是毫秒 60s=1分钟
=========连接超时=========
# 关闭abanded连接时输出错误日志,预生产/生产不建议开启,对性能影响
spring.datasource.logAbandoned = false
# 是否清除已经超过“removeAbandonedTimout”设置的无效连接。
spring.datasource.removeAbandoned = true
# 连接超过指定时间未关闭,就会被强行回收 180s=3分钟
spring.datasource.removeAbandonedTimeoutMillis = 180000
四、源码剖析
看完配置,大家心里还是懵逼对吧,参数如何生效,druid到底如何运行?
下面,带着问题,深入源码,直接剖析druid如何申请连接、释放连接、连接泄露检查。
4.1.申请连接
最终跟进到DruidDataSource的getConnectionDirect(long maxWaitMillis),获取得到连接后,validationQuery有效性检查,源码如下:

1.testOnBorrow =true,先直接校验,执行validationQuery,失败就关闭连接JdbcUtils.close(realConnection);
2.testWhileIdle=true,如果testOnBorrow =false, 测试空闲的连接,执行validationQuery,失败就关闭连接JdbcUtils.close(realConnection);
3.removeAbandoned=true,如果开启了泄露回收:把连接添加进Map<DruidPooledConnection, Object> activeConnections 。供泄露回收时使用。
分支1和2只会有一个执行。
4.2.释放连接
德鲁伊连接池在获取连接时,会调用一次DruidDataSource的init()。方法中createAndStartDestroyThread()开启了一个销毁线程。

销毁连接的线程包含了run(),如下:

在一个for空条件循环中,根据配置的timeBetweenEvictionRunsMillis连接检测间隔时间,执行一次DestroyTask.run()就休眠一次间隔时间。未设置默认60s。(实际源码中定义了60spublic static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 60 * 1000L;,所以用户未设置,默认60s,上图中else分支sleep1秒不会执行到)
追踪DestroyTask.run()如下:

2个步骤:
- shrink()收缩校验
- removeAbandoned()连接泄露移除
shrink()收缩校验
DruidDataSource内部定义了DruidConnectionHolder[] 类型的3个数组:
- 1.connections:可用连接数组。申请连接就从这里数组队尾拿连接。
- 2.evictConnections:待移除连接数组。
- 3.keepAliveConnections:待保活检测数组。
塞进数组
shrink()中计算出需要校验的数量checkCount,执行收缩校验核心逻辑:
- 校验物理连接的超时时间phyTimoutMills:超时放入evictConnections中,等待移除。
- 空余时间大于minEvictableIdleTimeMillis(受保最小空闲时间),并且索引(poolingCount)小于checkCount的连接则放入evictConnections;
- 空余时间大于minEvictableIdleTimeMillis(受保最小空闲时间),并且索引大于checkCount的连接,假若空余时间大于maxEvictableIdleTimeMillis则放入evictConnections,否则放入keepAliveConnections中进行keepAlive检测。
如下图:

数组处理
1.evictConnections:待移除连接数组。使用JdbcUtils.close() 关闭连接。

2.keepAliveConnections:待保活检测数组。根据配置的validationQuery查询SQL执行连接可用性校验。校验通过后再put(holder)塞进connections可用连接数组。

4.3.泄露连接移除
如果开启了removeAbandoned ,执行removeAbandoned()。移除泄露连接逻辑如下:

实际上,就是对可能的连接泄露(打开连接后长时间不关闭)兜底。
1)遍历活跃连接Map<DruidPooledConnection, Object> activeConnections。
2)跳过运行中的连接,running定义:执行SQL前赋值true ,执行完后置false。---》问题1得到答案,不会暴力关闭执行中的连接。
3)如果当前连接已连接时间>=removeAbandonedTimeoutMillis ,直接从activeConnections map 中移除。
这里消耗性能主要两步骤:
- 1.内存中记录+移除泄露连接
- 2.打印相关日志的IO---》logAbandoned=false 可关闭写日志
spring 的druid 连接池一般不会造成泄露。如果出现连接泄露,应该找到问题解决。---》问题2得到答案,目前关闭了写日志,就剩下了第一点“内存占用+过滤的性能”成本,要求不高的场景可以作为兜底方案使用。如果项目已稳定,推荐关闭。
五.分析&总结
本节为我们根据:申请、释放连接相关的参数配置,剖析策略是否合理。
5.1 配置分析
spring.datasource.testOnBorrow = false 申请连接时执行validationQuery检测连接是否有效
spring.datasource.testOnReturn = false 归还连接时执行validationQuery检测连接是否有效
spring.datasource.testWhileIdle = true testOnBorrow=false时才生效,申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
spring.datasource.initialSize = 5 初始连接数 5
spring.datasource.maxActive = 100 最大连接数
spring.datasource.minIdle = 5 最小空闲连接数 5
timeBetweenEvictionRunsMillis= 60000 60s=1分钟检测一次
minEvictableIdleTimeMillis=300000 300s=5分钟 最小空闲不移除时间
maxEvictableIdleTimeMillis 未设置最大空闲移除时间,默认DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 60L * 7 = 7小时。
keepAlive: 未设置保活开关,默认false关闭。不执行保活测试策略。
上述配置对应的策略:
1.初始策略
初始5个连接,最多可开启100个连接。
2.申请策略
申请连接的时候检测,如果连接空闲时间大于1分钟(检测间隔时间),执行validationQuery检测连接是否有效。---》这里可确保我们空闲时间超过1分钟的连接,校验后使用。
3.回收策略
每一分钟执行一次检测,策略如下:
1.连接空闲小于5分钟,不移除。
2.连接空闲大于5分钟,保留”minIdle设置的5个idle连接”,可移除(总数-5)个连接。
3.连接空闲大于7小时,可移除“minIdle设置的5个idle连接”。---》因为没有设置maxEvictableIdleTimeMillis ,默认空闲7小时后才会移除。不过一共就5个倒也没什么事。
4.连接空闲5分钟~7小时,由于没开启keepAlive保活开关,无法对“minIdle设置的5个idle连接”保活测试。-->minIdle设置的5个idle连接,这段时间一直不回收,也不做保活测试,连接是否有效无法保证。
5.2总结
1.现有项
removeAbandoned=true 开启连接泄露检测,要求不高的场景可以作为兜底方案使用。如果项目已稳定,推荐关闭。
2.可添加项
phyTimeoutMillis:看需要开启。物理超时时间。不管空闲时间,超时直接移除。---》这个是终极兜底方案,可以确保超时强制移除。
maxEvictableIdleTimeMillis:建议开启,实现精细化控制。
keepAlive: 建议开启。可针对“minIdle设置的空闲连接”,进行保活测试,从而提升连接的质量。
postgreSql最佳配置详解(connection 申请、回收策略)的更多相关文章
- druid 参数配置详解
druid 参数配置详解 */--> druid 参数配置详解 Table of Contents 1. 初始化连接 2. 参数配置及说明 3. 注意事项 3.1. 底层连接 3.2. 空闲检查 ...
- 阿里云slb和ucloud负载均衡ulb添加ssl证书将http服务https化的配置详解
阿里云和ucloud服务器配置ssl证书将http服务https化的配置详解 项目背景: 苹果App于2017年1月1日将启用App Transport Security安全功能,即强制App通过HT ...
- Tomcat记录-tomcat常用配置详解和优化方法(转载)
常用配置详解 1 目录结构 /bin:脚本文件目录. /common/lib:存放所有web项目都可以访问的公共jar包(使用Common类加载器加载). /conf:存放配置文件,最重要的是serv ...
- tomcat常用配置详解和优化方法
tomcat常用配置详解和优化方法 参考: http://blog.csdn.net/zj52hm/article/details/51980194 http://blog.csdn.net/wuli ...
- [转]阿里巴巴数据库连接池 druid配置详解
一.背景 java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色 ...
- redis配置详解
##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...
- JSHint配置详解
Also available on Github JSHint配置详解 增强参数(Enforcing Options) 本类参数设为true,JSHint会产生更多告警. bitwise 禁用位运算符 ...
- 日志分析工具ELK配置详解
日志分析工具ELK配置详解 一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分 ...
- springdata+redis配置详解
springdata设计初衷是位简化数据类型和数据的持久化存储,它并不局限是关系型数据库还是nosql数据库,都提供了简化的数据库连接,让数据获取变得更加的简单.所有这些的实现有统一的api提供. 本 ...
- CentOS6.5下VNC Server远程桌面配置详解
参考文献: (总结)CentOS Linux下VNC Server远程桌面配置详解 远程桌面连接工具VNC——license Key 我的下载地址为 太平洋下载 VNC连接黑屏的问题 centos 6 ...
随机推荐
- 在mac中双击执行python
执行python脚本 mac有内置的python,但还是建议你自己安装一个python,如果没有卸载mac自带的python2.7,当你需要使用python3执行脚本时,python命令需要改为pyt ...
- 基于知识图谱的《红楼梦》人物关系可视化及问答系统(含码源):命名实体识别、关系识别、LTP简单教学
基于知识图谱的<红楼梦>人物关系可视化及问答系统(含码源):命名实体识别.关系识别.LTP简单教学 文件树: app.py是整个系统的主入口 templates文件夹是HTML的页面 |- ...
- 6.6 Windows驱动开发:内核枚举Minifilter微过滤驱动
Minifilter 是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使 ...
- Typora Mac中文破解版获取
作为程序员,markdown是非常好用的文本编辑语言,而Typora是非常好用的一款markdown编辑工具.Typora提供读者和作家的无缝体验.它删除了预览窗口,模式切换器,降低源代码的语法符号以 ...
- (C语言)每日代码||2023.12.25||函数传参,传入数组时传递的是数组首元素地址
向函数传入某数组时,可以在函数内修改该数组的元素. #include <stdio.h> void test(char* p, char arr[]) { *p = 'h';//能改变 * ...
- spring-cloud 配置管理
作用: 实现配置热更新 实现网关配置热部署 配置模板 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc ...
- 转载洛谷:23.08.19 普及模拟1 T1
Past 题目描述 所有人,都有一段支离破碎的过去. 你有\(n\)段过去的经历,有时顺利,有时不顺,于是你用一个评价值\(a_i\)来描述你的第\(i\)段经历,它们构成了长度为\(n\)的序列\( ...
- 扩展说明: 指令微调 Llama 2
这篇博客是一篇来自 Meta AI,关于指令微调 Llama 2 的扩展说明.旨在聚焦构建指令数据集,有了它,我们则可以使用自己的指令来微调 Llama 2 基础模型. 目标是构建一个能够基于输入内容 ...
- P1405 苦恼的小明 题解
题目传送门 前置知识 扩展欧拉定理 解法 本题幂塔是有限层的,这里与 luogu P4139 上帝与集合的正确用法 中的无限层幂塔不同,故需要在到达递归边界 \(n+1\) 时进行特殊处理,对于处理 ...
- 使用python 打包成exe文件
python 打包exe 起因:闲的蛋疼 过程:扯的蛋疼 结果:不疼了 1.起因(闲的蛋疼) 突然的emo,不想干活,于是乎找遍微信好友,群发了十年八辈子不联系的一群人(此办法学习 ...