专注南昌网站建设,wordpress怎么查看源代码,做网站单网页,wordpress页面都在一、引子合理配置一个应用的数据库参数#xff0c;使其运行良好#xff0c;这很重要。本文以某务中台的生产环境为例#xff0c;从Apollo上拔下来一套配置#xff0c;分析是否合理。二、MybatisPlus配置由于我们使用Apollo配置参数#xff0c;所以分两部分#xff1a;1.个…一、引子合理配置一个应用的数据库参数使其运行良好这很重要。本文以某务中台的生产环境为例从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,table2mybatis-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.mergeSqltrue;druid.stat.slowSqlMillis5000 通过connectProperties属性来打开mergeSql功能慢SQL记录5秒spring.datasource.type com.alibaba.druid.pool.DruidDataSource 使用德鲁伊连接池spring.datasource.driver-class-name org.postgresql.Driver 驱动类名spring.datasource.url xx 数据库连接urlspring.datasource.username ${dbUserName} 用户名spring.datasource.password ${dbPassword} 密码spring.datasource.minIdle 5 最小空闲连接数 5spring.datasource.initialSize 5 初始连接数 5spring.datasource.maxActive 100 最大连接数spring.datasource.maxWait 60000 获取连接等待超时的时间 60s1分钟spring.datasource.filters stat,wall 监控统计拦截用于监控界面sql统计spring.datasource.poolPreparedStatements false 是否启用缓存PreparedStatementsspring.datasource.maxPoolPreparedStatementPerConnectionSize 20 指定每个连接上preStatement缓存数---》未生效健康检查spring.datasource.validationQuery SELECT 1 连接池的健康检查SQLspring.datasource.testOnBorrow false 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。spring.datasource.testOnReturn false 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能spring.datasource.testWhileIdle true 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。#每timeBetweenEvictionRunsMillis毫秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止spring.datasource.minEvictableIdleTimeMillis 300000 最小可驱逐空闲时间连接保持空闲而不被驱逐的最长时间单位是毫秒 300s5分钟spring.datasource.timeBetweenEvictionRunsMillis 60000 间隔多久才进行一次驱逐检测单位是毫秒 60s1分钟连接超时# 关闭abanded连接时输出错误日志预生产/生产不建议开启对性能影响spring.datasource.logAbandoned false# 是否清除已经超过“removeAbandonedTimout”设置的无效连接。spring.datasource.removeAbandoned true# 连接超过指定时间未关闭就会被强行回收 180s3分钟spring.datasource.removeAbandonedTimeoutMillis 180000四、源码剖析看完配置大家心里还是懵逼对吧参数如何生效druid到底如何运行下面带着问题深入源码直接剖析druid如何申请连接、释放连接、连接泄露检查。4.1.申请连接最终跟进到DruidDataSource的getConnectionDirect(long maxWaitMillis)获取得到连接后validationQuery有效性检查源码如下1.testOnBorrow true,先直接校验执行validationQuery失败就关闭连接JdbcUtils.close(realConnection);2.testWhileIdletrue,如果testOnBorrow false, 测试空闲的连接执行validationQuery失败就关闭连接JdbcUtils.close(realConnection);3.removeAbandonedtrue,如果开启了泄露回收把连接添加进Map 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 activeConnections。2)跳过运行中的连接running定义执行SQL前赋值true ,执行完后置false。---》问题1得到答案不会暴力关闭执行中的连接。3)如果当前连接已连接时间removeAbandonedTimeoutMillis 直接从activeConnections map 中移除。这里消耗性能主要两步骤1.内存中记录移除泄露连接2.打印相关日志的IO---》logAbandonedfalse 可关闭写日志spring 的druid 连接池一般不会造成泄露。如果出现连接泄露应该找到问题解决。---》问题2得到答案目前关闭了写日志就剩下了第一点“内存占用过滤的性能”成本要求不高的场景可以作为兜底方案使用。如果项目已稳定推荐关闭。五.分析总结本节为我们根据申请、释放连接相关的参数配置剖析策略是否合理。5.1 配置分析spring.datasource.testOnBorrow false 申请连接时执行validationQuery检测连接是否有效spring.datasource.testOnReturn false 归还连接时执行validationQuery检测连接是否有效spring.datasource.testWhileIdle true testOnBorrowfalse时才生效申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。spring.datasource.initialSize 5 初始连接数 5spring.datasource.maxActive 100 最大连接数spring.datasource.minIdle 5 最小空闲连接数 5timeBetweenEvictionRunsMillis 60000 60s1分钟检测一次minEvictableIdleTimeMillis300000 300s5分钟 最小空闲不移除时间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.现有项removeAbandonedtrue 开启连接泄露检测要求不高的场景可以作为兜底方案使用。如果项目已稳定推荐关闭。2.可添加项phyTimeoutMillis看需要开启。物理超时时间。不管空闲时间超时直接移除。---》这个是终极兜底方案可以确保超时强制移除。maxEvictableIdleTimeMillis建议开启实现精细化控制。keepAlive: 建议开启。可针对“minIdle设置的空闲连接”进行保活测试从而提升连接的质量。