发布于2021-06-08 09:29 阅读(1111) 评论(0) 点赞(23) 收藏(0)
某个下午,某个服务的测试环境突然出现大量接口延时告警,从监控上看,接口p99耗时基本都达到了5s以上,而且接口延时越来越长
随着业务方的不断超时重试,数据库线程被打满,等待线程数飙高,大量线程阻塞
1、通过APM链路监控,我们发现所有链路的主要耗时都集中在了DataSource#getConnection这个过程中
2、初步怀疑,可能是因为存在SQL 慢查询导致,但后来发现根因并不在此,因为监控显示,当时最慢的SQL99线是56.99ms,qps低于0.01(基本可以排除SQL慢查询这个原因)
3、GC分析:半个小时有289次GC,最长的的STW是280ms(在执行垃圾回收时,Java应用程序中除了垃圾回收器线程之外其他所有线程都被挂起,意味着在此期间,用户正常工作的线程全部被暂停下来,当初怀疑STW280ms影响到了DataSource#getConnection,但事实并不是,因为STW大于100ms到占比只有1.73%,比例不高)
4、接口QPS分析:在服务单实例的前提下,测试同学在循环跑用例导致这3个接口的请求数均达 3000次/min,平均1s要处理3000/60=50个请求,而线上这3个接口的平均耗时 20~30ms,当时有怀疑这三个接口的请求负载影响到其它接口相关线程的正常运作,但是这个并不能解释Java线程等待MySQL连接耗时如此之长
初步解决措施: 随着电话被打爆、微信被业务疯狂轰炸,为了尽快先解决问题,我们尝试扩展容器到三台,问题得到奇迹般缓解
1、在初步的分析中,总结出的初步结论是因为单实例下单个接口3000次/min次请求影响到了其他接口的正常查询,但是这并不能解释DataSource#getConnection耗时长的问题,因此需要进一步排查问题,深究原因
2、为了复现问题,我使用Jmeter以3000qpm来请求当时问题出现时,耗时最长的两个接口,但是问题没有复现,接口响应速度很快,平均响应时间都在10ms以内
3、为了进一步复现问题,我还原Apollo配置到服务异常的时间点(这个时候发现Druid 的配置test-on-borrow和test-on-return并修改成了false,后面发现这两个配置的修改成为的问题修复的关键),然后重启Jmeter,问题重现,DataSource#getConnection长达3s
4、使用Arthas 追查DataSource#getConnection的调用链路,分析其链路耗时,命令:trace com.alibaba.druid.pool.DruidDataSource getConnection ‘#cost > 100’ -n 5
通过一层层分析,我们最终来到了com.alibaba.druid.util.MySqlUtils#getLastPacketReceivedTimeMs这个方法
结合对代码的分析,我们发现在Druid 1.1.22版本的源码中,存在对com.mysql.jdbc.MySQLConnection类的加载,而当前我们当前使用的mysql-connector 8.x版本中是不存在这个类的(8.x 使用的是com.mysql.cj.MysqlConnection),导致com.alibaba.druid.util.Utils#loadClass会频繁地对一个不存在的类进行加载,影响服务的整体性能(根因)
5、在第3点中,我们提到:Druid 的配置test-on-borrow和test-on-return修改成了false,后面发现这两个配置的修改成为的问题修复的关键。
原因在于: 当testOnBorrow和testOnReturn 为True时,都会调用方法this.testConnectionInternal,而this.testConnectionInternal包含了对com.alibaba.druid.util.MySqlUtils#getLastPacketReceivedTimeMs这个方法的调用,然后触发了在第4点中提到的Bug,感兴趣的同学可以翻阅一下源码
原文链接:https://blog.csdn.net/BTBO_/article/details/117632093
作者:飞向远方
链接:http://www.javaheidong.com/blog/article/219100/68515103b82bf5481eda/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!