线上问题处理案例:出乎意料的数据库连接池

这篇具有很好参考价值的文章主要介绍了线上问题处理案例:出乎意料的数据库连接池。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

导读

本文是线上问题处理案例系列之一,旨在通过真实案例向读者介绍发现问题、定位问题、解决问题的方法。本文讲述了从垃圾回收耗时过长的表象,逐步定位到数据库连接池保活问题的全过程,并对其中用到的一些知识点进行了总结。

一、问题描述

大促期间,某接口超时次数增多,经排查直接原因是GC耗时过长,查看监控FullGC达500ms以上,接口超时时间与FullGC发生时间吻合。

线上问题处理案例:出乎意料的数据库连接池

图1 FullGC耗时监控

二、应用基本情况

  • 容器:8C12G;
  • JVM配置:-XX:+UseConcMarkSweepGC -Xms6144m -Xmx6144m -Xmn2048m -XX:ParallelGCThreads=8 -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ParallelRefProcEnabled;
  • 数据库类型:MySQL;
  • 数据库连接池:DBCP;

三、排查过程

1、 GC耗时过长,说明内存中垃圾对象很多。

2、 首先怀疑是否有内存泄漏,观察FullGC后堆内存回收情况,尚属正常,暂时排除内存泄漏原因。

线上问题处理案例:出乎意料的数据库连接池

图2 发生FullGC后堆内存回收监控

3、 推断FullGC耗时过长是否因为老年代有大量死亡对象,遂导出FullGC前后堆内存dump,通过比对“保留大小”,发现FullGC后大量数据库相关对象被回收。

线上问题处理案例:出乎意料的数据库连接池

图3 堆内存对象分析

4、 数据库连接正常应该不会频繁创建和断开,进入老年代后,正常不应该被回收,通过堆dump内容OQL分析每个数据库连接数量,发现很多库连接数都大于“maxActive”数量,可以肯定有很多失效连接。

5、 初步判断直接原因是很多失效数据库连接进入老年代,导致FullGC耗时过长。

6、 怀疑连接池验证周期过长,导致数据库因空闲过长关闭连接,将连接池参数“
timeBetweenEvictionRunsMillis”由1分钟调整到10秒,问题依旧。

7、 阅读DBCP源码,发现是通过
org.apache.commons.pool.impl.GenericObjectPool.Evictor定时任务,按照timeBetweenEvictionRunsMillis配置的周期定时驱逐失效连接,驱逐条件:若连接空闲时间大于“minEvictableIdleTimeMillis”,则会驱逐连接,等待垃圾回收。若开启“testWhileIdle”则会执行“validationQuery”。进一步阅读代码,发现执行“validationQuery”后,连接空闲时间并不会重新计算,导致连接在业务低谷时很容易被淘汰,而数据库连接会关联大量对象,创建、回收成本昂贵,并且影响GC。

8、 反向思考,为何只有在大促期间才发生问题?

线上问题处理案例:出乎意料的数据库连接池

图4 平时和大促时回收频率对比

可以看到平时由于业务量小,GC不频繁,过期连接没有达到进入老年代阈值,在年轻代被回收。而大促时业务量大,GC频繁,连接在进入老年代以后才过期,导致老年代FullGC时间过长。

9、 至此,基本可以肯定问题原因是数据库连接池不具备“保活”能力,导致连接不断淘汰和新建,在业务高峰时段,连接进入老年代然后失效,造成FullGC耗时过长,最终导致接口超时次数增多。

四、解决方案

方案1:改为G1回收器,对老年代回收是分块进行,可以防止长时间停顿。另外默认MaxTenuringThreshold值是15,可以防止失效连接过早进入老年代;

方案2
minEvictableIdleTimeMillis设置为0,使数据库连接不会自动失效,进入老年代以后一直存活,避免在老年代失效回收;

五、问题总结

数据库连接池并不具备通常理解的“保活”能力,数据库连接在业务不活跃的应用中,会不断淘汰和重连,而连接会通过虚引用方式(
com.mysql.jdbc.NonRegisteringDriver$ConnectionPhantomReference)携带大量对象,如果连接存活时间内YGC次数达到寿命阈值,则会进入老年代,老年代是使用“标记-清除”算法,回收成本更高,进而造成FullGC耗时过长。

六、拓展知识点

1、 Druid连接池同样存在不能“保活”问题,较新版本提供“KeepAlive”选项(未验证);

2、 Druid连接池配置的“validationQuery”语句通常并不会被执行,MySqlValidConnectionChecker在检查连接有效性时,会判断驱动是否实现pingInternal方法,如果实现则会通过此方法验证有效性。MySQL的JDBC驱动实现了该方法,因此“validationQuery”配置的语句通常不会执行;

线上问题处理案例:出乎意料的数据库连接池

图5 连接有效性校验代码

3、 DBCP和Druid连接池默认都是FILO,如果业务不繁忙,会导致只有最前边的连接被使用-归还-使用,后边连接基本都在无谓的驱逐、重建连接;

4、 虚引用对GC的影响:这些引用只有经过两次GC才能被回收掉,如果进入老年代,则必须经过两次FullGC才能释放内存。本例中由于不断有新的虚引用对象在老年代失效,导致FullGC后,内存水位仍然偏高,会加剧GC压力。新版本JVM已对此做了优化,一次GC可以回收掉;

5、 类似的影响还有finalize方法;

6、 CMS回收器默认MaxTenuringThreshold为6,而ParallelGC和G1均默认15;

结语

本文对数据库连接失效引起的GC问题进行了详细分析,希望读者通过本文对数据库连接“保活”机制、GC问题基本分析方法有所收益,后续该系列文章会继续推出其他案例分享。

作者:京东零售 王利辉

内容来源:京东云开发者社区文章来源地址https://www.toymoban.com/news/detail-454829.html

到了这里,关于线上问题处理案例:出乎意料的数据库连接池的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • DVPP媒体数据处理视频编码问题案例

    DVPP(Digital Vision Pre-Processing)是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强大的媒体处理硬加速能力,主要功能包括图像编解码、视频编解码、图像抠图缩放等。 本期就分享几个关于 D VPP 视频编码 问题的典型案例,并给出原因分析及解决方法:

    2024年02月09日
    浏览(37)
  • openGauss学习笔记-192 openGauss 数据库运维-常见故障定位案例-XFS文件系统问题

    192.1 在XFS文件系统中,使用du命令查询数据文件大小大于文件实际大小 192.1.1 问题现象 在数据库使用过程中,通过如下du命令查询数据文件大小,查询结果大于文件实际的大小。 192.1.2 原因分析 XFS文件系统有预分配机制,预分配的大小由参数allocsize确定。du命令显示的文件大

    2024年02月02日
    浏览(51)
  • openGauss学习笔记-196 openGauss 数据库运维-常见故障定位案例-强制结束指定的问题会话

    196.1 强制结束指定的问题会话 196.1.1 问题现象 有些情况下,为了使系统继续提供服务,管理员需要强制结束有问题的会话。 196.1.2 处理办法 以操作系统用户omm登录主机。 使用如下命令连接数据库。 postgres为需要连接的数据库名称,8000为端口号。 从当前活动会话视图查找问

    2024年01月18日
    浏览(49)
  • openGauss学习笔记-198 openGauss 数据库运维-常见故障定位案例-分析查询效率异常降低的问题

    198.1 分析查询效率异常降低的问题 198.1.1 问题现象 通常在几十毫秒内完成的查询,有时会突然需要几秒的时间完成;而通常需要几秒完成的查询,有时需要半小时才能完成。 198.1.2 处理办法 通过下列的操作步骤,分析查询效率异常降低的原因。 使用analyze命令分析数据库。

    2024年01月16日
    浏览(60)
  • 昇腾实战丨DVPP媒体数据处理图片解码问题案例

    摘要: 本期就分享几个关于DVPP图片解码问题的典型案例,并给出原因分析及解决方法。 本文分享自华为云社区《DVPP媒体数据处理图片解码问题案例》,作者:昇腾CANN 。 DVPP(Digital Vision Pre-Processing)是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强

    2024年02月08日
    浏览(37)
  • py连接sqlserver数据库报错问题处理。20009

    pymssql模块连接sqlserver出现如下错误: 打开“SQL Server Configuration Manager”,找不到的话,可在计算机管理 - 服务和应用程序中找到。 在SQL Server Network Configuration - Protocols for SQLEXPRESS中启用TCP/IP协议, TCP/IP - Properties - IP Addresses 修改里面ip为127.0.0.1的启用状态。 TCP/IP - Properties

    2024年02月01日
    浏览(46)
  • es线上处理命令记录

    该模版下,创建的索引前缀都会使用这个模版 yst_crawler 1.设置别名 2 .查看状态 3.验证分词 4.把数据同步到新的索引 4.1 同步方式迁移 4.2 异步方式迁移,设置了9个并发 } 4.3 异步方式迁移,查看完成状态 5.修改别名,去除别名 6.验证数据 主要看数据量total 7.最后确认没问题后,

    2024年02月12日
    浏览(30)
  • Spring Boot使用jasypt处理数据库账号密码等数据加密问题

    在我们业务场景中,项目中的application.yml 配置文件比如数据库账号密码,的各种链接的username,password的值都是明文的,存在一定的安全隐患,可以使用jasypt 加密框架的方式进行明文加密,进而使得我们项目更加安全 注意这里排除了mybatis-plus的包可能是项目中有冲突依赖,

    2024年02月06日
    浏览(53)
  • 线上项目源码安全性处理方案

    场景: 最近项目提出要对线上代码进行安全性处理,防止客户直接通过反编译工具将代码反编译出来 方案: 第一种方案使用的是代码混淆 第二种方案使用的是代码加密 方案比较 方案一:采用的proguard-maven-plugin插件 方案二:采用的classfinal-maven-plugin插件 在单模块中方案一还

    2024年02月04日
    浏览(35)
  • Sql Server 占用内存高,不释放内存,数据库连接不上 问题处理记录

    项目上反应生产线箱码不能上传到我们系统,我们的WMS软件退出后重新登录也一直登录失败,并且服务器上数据库占用内存过高,SSMS数据库连接不上。 好家伙SQL Server占用了34个G内存。 接口日志中连接数据库报错:System.Data.SqlClient.SqlException: 当前命令发生了严重错误。应放弃

    2024年02月14日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包