一、引子

合理配置一个应用的数据库参数,使其运行良好,这很重要。本文以某务中台的生产环境为例,从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个步骤:

  1. shrink()收缩校验
  2. 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 申请、回收策略)的更多相关文章

  1. druid 参数配置详解

    druid 参数配置详解 */--> druid 参数配置详解 Table of Contents 1. 初始化连接 2. 参数配置及说明 3. 注意事项 3.1. 底层连接 3.2. 空闲检查 ...

  2. 阿里云slb和ucloud负载均衡ulb添加ssl证书将http服务https化的配置详解

    阿里云和ucloud服务器配置ssl证书将http服务https化的配置详解 项目背景: 苹果App于2017年1月1日将启用App Transport Security安全功能,即强制App通过HT ...

  3. Tomcat记录-tomcat常用配置详解和优化方法(转载)

    常用配置详解 1 目录结构 /bin:脚本文件目录. /common/lib:存放所有web项目都可以访问的公共jar包(使用Common类加载器加载). /conf:存放配置文件,最重要的是serv ...

  4. tomcat常用配置详解和优化方法

    tomcat常用配置详解和优化方法 参考: http://blog.csdn.net/zj52hm/article/details/51980194 http://blog.csdn.net/wuli ...

  5. [转]阿里巴巴数据库连接池 druid配置详解

    一.背景 java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色 ...

  6. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  7. JSHint配置详解

    Also available on Github JSHint配置详解 增强参数(Enforcing Options) 本类参数设为true,JSHint会产生更多告警. bitwise 禁用位运算符 ...

  8. 日志分析工具ELK配置详解

    日志分析工具ELK配置详解 一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分 ...

  9. springdata+redis配置详解

    springdata设计初衷是位简化数据类型和数据的持久化存储,它并不局限是关系型数据库还是nosql数据库,都提供了简化的数据库连接,让数据获取变得更加的简单.所有这些的实现有统一的api提供. 本 ...

  10. CentOS6.5下VNC Server远程桌面配置详解

    参考文献: (总结)CentOS Linux下VNC Server远程桌面配置详解 远程桌面连接工具VNC——license Key 我的下载地址为 太平洋下载 VNC连接黑屏的问题 centos 6 ...

随机推荐

  1. 利用 ASP.NET Core 开发单机应用

    前言 现在是分布式微服务开发的时代,除了小工具和游戏之类刚需本地运行的程序已经很少见到纯单机应用.现在流行的Web应用由于物理隔离天然形成了分布式架构,核心业务由服务器运行,边缘业务由客户端运行.对于 ...

  2. 手把手带你上手swagger3

    配置POM 只需要加一个依赖,并且要注意,swagger3在springboot2.5版本以上会出现问题 <dependency> <groupId>io.springfox& ...

  3. Hbase-执行hbase shell命令时提示:ERROR: KeeperErrorCode = NoNode for /hbase/master

    1.问题描述 执行hbase  shell命令时提示: ERROR: KeeperErrorCode = NoNode for /hbase/master 2.问题原因 这是与因为服务器重启后Hado ...

  4. 2024年,我又开始用Linux桌面作为主力系统了~

    前言 19年的时候我买了一个 matebook14 笔记本,配置是8代i5和8G内存,在当时看来作为轻薄本是够用的,但是现在已经2024年了,这内存让我想起来去年苹果的新款 mac mini ,丐版三 ...

  5. Pandas 美国竞选捐赠案例

    import pandas as pd """ 需求 1.加载数据 2.查看数据的基本信息 3.指定数据截取,将如下字段的数据进行提取,其他数据舍弃 cand_nm: 候 ...

  6. typora beta版本 typora免费版 typora 0.11.18 下载

    壹 ❀ 引 typora从1.0.0正式版开始就不再免费了,可能有一些开了自动检测更新的同学,在某次打开typora就看到了购买以及试用天数的弹窗,但typora正式之前的beta版依旧免费,这里就分 ...

  7. Object.definePropety

    defineProperty Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象,也就是说,该方法允许精确地添加或修改对象的属 ...

  8. Laravel入坑指南(5)——请求与响应

    作为互联网典型的Web应用,接收用户请求的数据,并将处理的结果向用户进行响应,是最基础也是最必备的功能.在原生的PHP中,我们常用$_POST.$_GET.$_REQUEST和$_FILES对不同的请 ...

  9. Oracle DBMS_UTILITY.GET_TIME与DBMS_UTILITY.GET_CPU_TIME区别

    DBMS_UTILITY.GET_TIME与DBMS_UTILITY.GET_CPU_TIME比较 原文链接: http://www.oracle-developer.net/display.php? ...

  10. spring boot实现验证码登录

    内容比较简单,需要完整项目的朋友留下邮箱,给你们发. 直接看效果: 下面是实现步骤 1.验证码生成工具类(引用自网络) package com.laoxu.test.helloweb.util; im ...