【调优案例】druid testOnBorrow参数问题
发布日期:2021-06-30 21:35:44 浏览次数:3 分类:技术文章

本文共 3362 字,大约阅读时间需要 11 分钟。

在性能优化调优数据库连接池配置

调优效果

修改前:

spring.datasource.type = com.alibaba.druid.pool.DruidDataSourcespring.datasource.druid.initial-size = 20spring.datasource.druid.max-active = 50spring.datasource.druid.min-idle = 20spring.datasource.druid.max-wait = 5000spring.datasource.druid.validation-query = select 1spring.datasource.druid.test-on-borrow = truespring.datasource.druid.test-on-return = truespring.datasource.druid.test-while-idle = truespring.datasource.druid.time-between-eviction-runs-millis = 60000spring.datasource.druid.min-evictable-idle-time-millis = 60000

修改后:

spring.datasource.type = com.alibaba.druid.pool.DruidDataSourcespring.datasource.druid.initial-size = 3spring.datasource.druid.max-active = 15spring.datasource.druid.min-idle = 3spring.datasource.druid.max-wait = 5000spring.datasource.druid.validation-query = select 1spring.datasource.druid.test-on-borrow = falsespring.datasource.druid.test-on-return = falsespring.datasource.druid.test-while-idle = truespring.datasource.druid.time-between-eviction-runs-millis = 60000spring.datasource.druid.min-evictable-idle-time-millis = 180000

优化的效果为:

  1. tps提升2倍+
  2. 服务器cpu从350% 下降为 40%

疑问点

因为主要调试的是连接数,但是连接数变小主要是减少数据库连接线程的切换,降低cpu使用,理论上cpu足够时,tps不会出现这么显著的提升,而且cpu降低的过于离谱

既然理论上解释不了,那就实践一波可能的影响因素

通过控制唯一变量的方式,首先修改 spring.datasource.druid.test-on-borrow 这个,将false 修改回 true

这个时候发现:

  1. tps仅比一开始提升1.5倍
  2. 服务器cpu仍然为350%

同样的方式试验其余变量

OK,初步断定参数 test-on-borrowtest-on-return 这两个配置项的影响

网上资料

mysql调优中关注的参数:

validationQuery

用来检测连接是否有效的sql,如果validationQuery为空,那么testOnBorrow、testOnReturn、testWhileIdle这三个参数都不会起作用,因为这三个参数都是通过执行参数validationQuery指定的SQL来验证数据库连接的有效性,配置参考:validationQuery=SELECT 1

testWhileIdle

建议配置为true。对性能影响很小,因为是定期检查。如果连接空闲时间大于timeBetweenEvictionRunsMillis指定的毫秒,就会执行参数validationQuery指定的SQL来检测连接是否有效。

testOnBorrow

建议配置为false。获取连接时执行validationQuery检测连接是否有效,这个配置会降低性能。

testOnReturn

建议配置为false。归还连接时执行validationQuery检测连接是否有效,这个配置会降低性能。

如果这4个参数都是按照上面建议进行配置,那么就不会有什么性能问题,

但是,下面这张压测表格 testOnReturn和testOnBorrow 不同值组合的情况下,5000次主键查询的耗时比较:
在这里插入图片描述
由这张压测结果表,我们可以得出如下结论:

testOnReturn和testOnBorrow都为false时性能最好。

如果任意一个参数为true(另一个为false),会导致性能下降5倍多。

testOnReturn和testOnBorrow对性能的影响几乎一样(因为它们都会通过执行参数validationQuery指定的SQL来校验连接的有效性)

事实上,这两个参数在druid中默认值就是false

arthas问题定位

通过apm链路监控,可以得到主要耗时在获取当前数据库连接耗时getConnection,代码入口

@Override    public DruidPooledConnection getConnection() throws SQLException {
return getConnection(maxWait); } public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init(); if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this); return filterChain.dataSource_connect(this, maxWaitMillis); } else {
return getConnectionDirect(maxWaitMillis); } }

安装arthas 并追踪链路耗时

wget https://alibaba.github.io/arthas/arthas-boot.jarjava -jar arthas-boot.jar

在这里插入图片描述

通过一层层定位并结合druid代码

trace com.alibaba.druid.pool.DruidDataSource pollLast  '#cost > 10' -n 3

在这里插入图片描述

发现在代码中

在这里插入图片描述

需要加载类 com.mysql.jdbc.MySQLConnection,而当前mysql-connector 8.X的驱动中并不存在,Utils.loadClass方法类加载生吞了异常,所以代码逻辑会频繁对不存在的类进行类加载

trace com.alibaba.druid.util.Utils loadClass  '#cost > 10' -n 3

在这里插入图片描述

接着实验执行10000次,当类存在时需要时间40ms+,当类不存在时需要3500ms,相差两个量级

优化

其实在druid的 中也有人提到此问题,且在1.1.24版本已经解决了该问题

所以在前面针对testOnReturn和testOnBorrow 性能5倍的优化是因为druid 1.1.10中的bug的结论,其实试验发现性能大概损耗不到10%,并没有前面得到的结论这么离谱

该问题mysql的官方建议配置项将配置 test-on-borrowtest-on-return 设置为false

转载地址:https://lluozh.blog.csdn.net/article/details/108766937 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【jmeter】dubbo接口java.util.List<MyClassVo>参数
下一篇:【Furion】执行的csv文件未找到

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月11日 13时42分14秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章