【历代文学】Druid连接池实战:搞懂6个参数,就能用好它
本文针对点连接可进入)的Druid数据源调优实战总结分享给大家!
(
历代文学网数据库数据量高达1TGB,收录来自古今中外 200多个朝代和国家的作者超 15万人,诗、词、曲、赋、文言文等作品数超 114万个,成语超 5万个,名句超 12万条,名言超 130万条,著作超 2万部。
在历代文学项目稳定上线前,曾多次经历数据库宕机重启后,Druid连接池无法自动恢复,除非手动重启应用程序,才能让Druid连接池自动恢复正常!
1. Druid实战场景简介
Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
Druid是一个开源项目,源码托管在github上,源代码仓库地址是:
https://github.com/alibaba/druid
1.1 Druid数据源介绍
阿里巴巴的Druid是一个JDBC组件,它包含三部分:DruidDriver代理、DruidDataSource数据库连接池和SQLParser。Druid是阿里巴巴的开源项目,该项目主要是为了监控数据库连接池的性能指标,提供可视化的操作界面。
Druid连接池的优点:
-
可以监控数据库池的状态,包括池的状态及每个活动连接的详细状态。
-
可以提供SQL监控功能,可以监控SQL的执行时间、执行次数、执行频率等。
-
可以提供数据库密码加密功能,提高系统安全性。
-
支持数据库分表分库,提供异常连接处理机制,提高系统稳定性。
1.2 你是否遇到数据库因故障重启后,druid却无法自动恢复?
实际项目中,你是否经常会遇到以下问题:
如下日志所示,数据库宕机,重启恢复后,druid连接池却依然死翘翘,无法自动恢复,如下错误日志所示:
数据库宕机,再恢复数据库启动后,应用服务器的druid连接池,因为没有重启服务器,导致迟迟不能恢复正常?这里一定要重启应用服务器才能让druid恢复正常吗?难道真的是Druid自己存在的bug,导致数据库宕机恢复后,自己却不能恢复么?还是我们没有学会使用Druid数据源的核心配置导致的?
答案显然不是Druid自身的bug,肯定是我们自己没用对导致的!想象一下也知道,别个都在一线大型互联网项目实战那么久了,岂能因你使用有误而被轻易推翻的?
1.3 搞懂Druid这几个核心参数用法很关键
本文重点介绍Druid数据源的如下几个关键的核心参数,搞懂它,一定让你真正玩好项目!不会再因为上述问题而烦恼:
- validationQuery
- testWhileIdle
- minEvictableIdleTimeMillis
- timeBetweenEvictionRunsMillis
- keepAlive
- keepAliveBetweenTimeMillis
2. Druid连接池6个核心参数详解
Druid数据源其实非常优秀的数据源,带有PreparedStatement缓存机制,性能非常高!但经常因为我们自己用不好,或是没有搞懂关于它的一些核心配置,从而导致恶性事件重复不止!
认真阅读本文,会让你接触上述困惑,只要搞懂这八个核心参数的组合使用,你不会再遇到上述druid连接池瘫痪的情况!
2.1 validationQuery
官方解释:用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
请注意,这个参数必须配置,而且配置了才会让testOnBorrow、testOnReturn、testWhileIdle这几个参数生效。如果不配,上述数据库宕机事故,druid连接池依然无法自动恢复正常的!
2.2 validationQueryTimeout
官方解释:单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法。
该参数是配合上一个validationQuery一起使用的,不能太大,太大,会让检测时间太久,连接池恢复正常耗时很长!设置1-3秒比较合适。
2.3 testWhileIdle
官方解释:申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。建议配置为true,不影响性能,并且保证安全性。
官方实现代码如下:
这个就按官方建议来吧,配置为true!
2.4 minEvictableIdleTimeMillis
官方解释:连接保持空闲而不被驱逐的最小时间,即最小生存时间!见如下代码:
销毁连接时,当检测到当前连接的最后活动时间和当前时间差(即连接的空闲时间)大于该值时,关闭当前连接。
连接的空闲时间大于 minEvictableIdleTimeMillis(连接保持空闲而不被驱逐的最小时间), 则进行回收。
2.5 timeBetweenEvictionRunsMillis
官方解释:
有两个含义:
- Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
- testWhileIdle的判断依据,详细看testWhileIdle属性的说明。
正确理解:
- 如果testWhileIdle为true,距离上次激活时间超过timeBetweenEvictionRunsMillis,则进行连接有效性检测,即执行validationQuery检测连接是否有效。
- 连接销毁线程(DestroyConnectionThread)该线程主要工作是将空闲及无效的连接销毁,可以通过timeBetweenEvictionRunsMillis 时间设置执行间隔。每次回收都是从connects 头部开始遍历;
DestroyConnectionThread线程主要回收以下几类连接:
- 连接的空闲时间大于 minEvictableIdleTimeMillis(连接保持空闲而不被驱逐的最小时间), 则进行回收。
- 大于minIdle 部分的连接会被回收。保证连接池空闲连接不会太多。
- 检查连接活跃度,不健康的连接则关闭。默认不检查,可以通过 druid.keepAlive 打开连接的健康检查。
2.6 keepAliveBetweenTimeMillis
官方解释:单位毫秒,若连接空闲时间大于keepAliveBetweenTimeMillis毫秒,执行一次有效性检测,检测不通过的连接会被销毁。
官方代码如下:
从上述代码可知,参数timeBetweenEvictionRunsMillis仅仅是销毁线程DestroyConnectionThread的运行周期!
Druid数据库连接池中还有一个销毁连接的线程,上述已提到,名叫DestroyConnectionThread,该线程会每间隔timeBetweenEvictionRunsMillis的时间执行一次DestroyTask任务来销毁连接,这些被销毁的连接可以是存活时间达到最大值的连接,也可以是空闲时间达到指定值的连接。
如果还开启了保活机制,那么空闲时间大于keepAliveBetweenTimeMillis的连接都会被校验一次有效性,校验不通过的连接会被销毁。
因此keepAliveBetweenTimeMillis一定要大于timeBetweenEvictionRunsMillis,前者是连接保持存货的最小生命值(毫秒),而后者是检测该生命值的线程的运行时间间隔!
3. 项目实战中Druid连接池的配置
以下是项目实战中的Druid连接池可靠性配置,可以保证数据库宕机重启后,应用无需重启都能很快恢复正常响应状态!根据实际需要,只需要修改maxActive值即可!
4. 总结
本文中,我们详细介绍了Druid连接池的几个核心参数配置,通过对这些配置介绍,能使我们能更准确的了解Druid,然后感受Druid的高性能,可靠性设计的迷人之处!支持国产数据源,支持Druid!
- 点赞
- 收藏
- 关注作者
评论(0)