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 ...
随机推荐
- 从零开始配置vim(27)——代码片段
我们之前介绍过缩写相关的内容,缩写是可以自动帮我们将缩写的单词展开成一段完整的话.但是代码本身是结构话的,仅仅使用缩写来配置是无法完成自动生成代码这个步骤的.好在我们大量的插件来进行配置.本篇我们将要 ...
- 深度学习基础入门篇[六]:模型调优,学习率设置(Warm Up、loss自适应衰减等),batch size调优技巧,基于方差放缩初始化方法。
深度学习基础入门篇[六]:模型调优,学习率设置(Warm Up.loss自适应衰减等),batch size调优技巧,基于方差放缩初始化方法. 1.学习率 学习率是训练神经网络的重要超参数之一,它代表 ...
- 【7】vscode不同的窗口样式和颜色插件peacock、设置打开多个窗口、md文件打开方式和预览以及插入目录
相关文章: [1]VScode中文界面方法-------超简单教程 [2]VScode搭建python和tensorflow环境 [3]VSCode 主题设置推荐,自定义配色方案,修改注释高亮颜色 [ ...
- BoostAsyncSocket 异步反弹通信案例
Boost 利用ASIO框架实现一个跨平台的反向远控程序,该远控支持保存套接字,当有套接字连入时,自动存储到map容器,当客户下线时自动从map容器中移除,当我们需要与特定客户端通信时,只需要指定客户 ...
- html的input type=file
文件上传:https://www.zhangxinxu.com/wordpress/2015/11/html-input-type-file/ some与every的使用:https://blog.c ...
- 开发者必看!苹果App Store重大调整:App上架必须有ICP备案号
日前,苹果App Store迎来重大调整,即日起中国大陆上架的App必须具备有效的互联网信息服务提供者(ICP)备案号. 简单说,新App现在需要填写备案号才能提审,这就要求开发者应用需有备案号,另外 ...
- 1.29 深痛教训 关于 unsigned
unsigned long long 无符号长长整型,常用于比 long long 大一倍的整数范围或自然溢出 \(\bmod 2^{64}\) unsigned long long 范围为 \(0\ ...
- 会话跟踪技术之SESSION
会话跟踪技术之SESSION 一般来说,登录信息既可以存储在session中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同 ...
- 5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
中台Admin(Admin.Core) 中台Admin(Admin.Core)是前后端分离权限管理系统,前端 UI 基于Vue3开发,后端 Api 基于.NET 8.0开发.支持多租户.接口权限.数据 ...
- MySQL中 int(11)和int(10)有没有区别!!
结论:int(11) int(3) int(20) 若不勾选填充0,那么效果统统一样,若勾选了填充0:查询出来的效果 会是这样: int(11) 00000000123 int(3) 123 ...