首页 > 其他分享 >记 Druid 连接池配置不当引发的服务卡慢宕机问题

记 Druid 连接池配置不当引发的服务卡慢宕机问题

时间:2024-08-19 10:04:51浏览次数:12  
标签:java 宕机 max druid Druid 服务卡 DruidDataSource alibaba com

背景

单体服务部署到 Tomcat 之后,运行一段时间,出现系统响应超时的情况。重启服务后正常,一段时间后重新出现。

排查

查看 CPU 信息发现正常,打开 jvisualvm,发现线程数持续上升,且没有下降趋势,此时初步判断系统在某个地方卡住了,请求进来后处理任务的线程都处于等待状态。

在 jvisualvm 中导出线程 Dump,到 fast thread 中进行分析,发现大量线程(80% 以上)处于 WAITING 状态,继续查看堆栈信息,发现大部分线程都阻塞 DruidDataSource.takeLast 中:

"http-nio-8008-exec-138" #98760 daemon prio=5 os_prio=0 tid=0x0000000042d7f800 nid=0x602c waiting on condition [0x00000000758ac000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000003c15c1328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:2002)
	at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1539)
	at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1326)
	at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5007)
	at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
	at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5003)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1304)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1296)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:109)
	...

想到可能是数据库连接池耗尽了。在网上发现有人遇到同样的问题 druid/issues/1160

解决

为什么会耗尽呢,结合网络上的分析,认为可能是数据库连接在某个地方没释放,也就是发生了泄露,连接一直得不到回收最后慢慢耗尽。于是配置了
removeAbandoned 和 removeAbandonedTimeout,发现无效,而且更严重的是出现了 CPU 飙升的情况,查看日志,估计是回收了流程引擎这类基础组件所用到的连接,导致出现意外的死循环。

考虑到项目上线初期并没有出现该问题,认为可能是随着数据量的增大,报表统计等慢 SQL 占用连接时间变长,加上用户量的上升,请求会变得比以前频繁,在并发较高时,就出现了连接池耗尽的情况。

于是本地启动应用,使用 jmeter 对报表接口连发了 100 个请求,结合 JProfiler 监控系统状态,发现果然线程数持续上升后一直没降下来,其他接口无法正常响应。

查看 druid 配置,发现 max-active、max-wait 未配置,为默认值。max-wait 默认 -1 也就是不超时,max-active 默认为 8。

再定位到 DruidDataSource.takeLast 被调用的位置,发现有如下逻辑:

if (maxWait > 0) {
    holder = pollLast(nanos);
} else {
    holder = takeLast();
}

这是在从阻塞队列中获取 holder,poll 在指定时间内如果获取失败了会直接返回,take 则会持续等待。于是设置了 max-wait 重新测试,发现超时后,线程数降下来了,但是超时时间内,系统还是无法正常响应。

其实最主要是要知道为什么会卡住不释放连接,但还是决定增大 max-active,提升处理并发的能力。重新测试,发现正常,上线后没再出现该问题。

总结

因为没有配置 max-active 和 max-wait,导致在并发数上升后,出现数据库连接池连接耗尽的情况,表现为系统卡住。加上配置后问题解决。

druid:
  max-active: 150
  max-wait: 60000

后记

其实第一次碰到没什么经验,刚开始怀疑是内存泄漏导致 OOM,但是日志和堆 Dump 中未发现问题,后面又怀疑是不是重启应用时缓存未正常处理,最后发现其实都不是。

另外,实际处理时也没有这么清晰的思路,也没有用到多少分析工具,倒是用 Arthas 监控过应用但是没找到问题。

所以处理完问题后,应该及时总结经验,理清思路,方便之后再遇到时及时解决。

参考:

Druid 获取连接超时,导致服务不可用

踩坑 DruidDataSource 导致的服务卡死

Alibaba Druid 数据库连接池 takeLast() AQS 死锁导致程序无响应

Druid 连接泄露记录

相关内容:

Druid-Source-Block 踩坑

工作笔记(一):Druid 连接池未正确设置参数导致的阻塞问题分析

java 打印堆栈文件 jstack 打印堆栈信息

如何用 Jstack 把 java 进程中的堆栈信息输出到文件

记一次线上 tomcat 服务器运行正常但是无响应问题排查

标签:java,宕机,max,druid,Druid,服务卡,DruidDataSource,alibaba,com
From: https://www.cnblogs.com/Higurashi-kagome/p/18366718

相关文章

  • 宝塔硬盘满了,宝塔不能登录,数据库宕机解决办法
    1.命令查看硬盘是否满了:df如果满了,清楚日志,清理磁盘打开SSH软件清理二进制日志:rm-f/www/server/data/ib_*rm-f/www/server/data/mysql-bin*启动数据库servicemysqldstart2.宝塔就可以连接上了,查看一下占满的原因:3)数据库日志占满,关闭日志就行了,需要打开的话重新打开4)......
  • 关闭Druid中某些错误日志打印
    xml配置情况下,需要修改数据源配置;<beanclass="com.alibaba.druid.pool.DruidDataSource"...> 注意这里删除了slf4j,对于slf4j单独写了filter,去除了statement执行错误的日志 <propertyname="filters"value="config,stat"/>  <propertyname="prox......
  • Springboot+logback+druid +密码加密 实现业务日志入库
    springboot配置spring:datasource:type:com.alibaba.druid.pool.DruidDataSourcedruid:#主库数据源master:driverClassName:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://xxx:3306/dbName?useUnicode=true&characterEncoding=u......
  • ; 每隔10分钟定时关闭并重启蘑菇游戏下载器,防止下载器卡死宕机死机停止下载的AutoHot
     ;每隔10分钟定时关闭并重启蘑菇游戏下载器,防止下载器卡死宕机死机停止下载的AutoHotkey脚本2024年8月7日  ;每隔10分钟定时关闭并重启蘑菇游戏下载器,防止下载器卡死宕机死机停止下载的AutoHotkey脚本2024年8月7日;测试环境:AutoHotkey_1.1.37.02_Setup.exe&Win......
  • 使用普罗米修斯API统计服务宕机时间
    使用/api/v1/query?query=mysql_global_status_uptime&time=查询服务上次启动时间使用/api/v1/query_rangeStringquery="mysql_global_status_uptime{instance=\""+startDTO.getInstance()+"\"}";查询某段时间内服务的数据变化通过60秒和1秒的step来分析出服务......
  • ORA-07445 opiaba()+639 ORA-00600 17147数据库宕机
    /u01/app/oracle/diag/rdbms/testaa/testaa/traceThuAug0112:43:372024ArchivedLogentry46044addedforthread1sequence23032ID0x860b01b0dest1:ThuAug0112:51:362024Exception[type:SIGSEGV,SI_KERNEL(general_protection)][ADDR:0x0][PC:0x1......
  • druid数据库连接池在使用中遇到的一些问题和说明
    getconnectiontimeoutretry:12024-02-0611:18:26.364ERROR23752---[eate-1838225797]com.alibaba.druid.pool.DruidDataSource:createconnectionSQLException,url:jdbc:oracle:thin:@192.168.66.88:1521:orcl,errorCode17002,state08006有正在执行的SQL......
  • 存储宕机导致Oracle异常故障处理---惜分飞
    联系:手机/微信(+8617813235971)QQ(107644445)标题:由于存储宕机导致Oracle异常故障处理作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]存储突然掉线,导致数据库crash,报大量ORA-00206ORA-00202ORA-15081以及Linux-x86_64Error:5:......
  • SpringBoot3.x整合Druid数据库连接池
    引入依赖<!--Druid数据库连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version></dependency......
  • 【YashanDB数据库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIE
    问题现象客户的java日志中有如下异常信息:问题的风险及影响对正常的业务流程无影响,但是影响druid的mergesql功能(此功能会将sql语句中的字面量替换为绑定变量,然后将替换以后的sql视为同一个,然后用做执行性能统计)问题影响的版本与yashandb版本无关问题发生原因druid源码中在......