32-一条SQL引发的系统卡死(上)-数据分析

简介: 今天给大家分享一个真实的案例,这是我之前一个朋友公司的项目在开发完毕后上线发现整个项目在线上的体验非常不好,有明显的频繁卡顿,后来经过一连串的排查、定位、分析和优化才发现原来是一条SQL引发的问题,而且该SQL语句是一位刚入职不久的工程师所写。通过这次事故的教训也让这个团队在后续的开发中更加注重了JVM参数的设置以及GC的监控。

该案例肯定涉及到整个项目的代码关联,无法给到大家具体代码的展示,我们本案例还是通过画图的方式给大家进行讲解。对于该案例的分析和优化的过程大家如果能理解透彻,举一反三,对于大家以后在自己公司的项目以及遇到类似的情况,能够结合我们讲解的Jvm知识和掌握的工具自己去进行排查和优化肯定是有帮助的。

JVM性能分析-找问题

那么针对类似这种系统上线后就比较卡顿的问题,我们应该如何下手去进行排查呢?

我们之前已经介绍过 jstat工具了,这个工具是非常好用、实用的一个工具,希望大家重视起来。

由于很多中小型公司其实都没有可视化的监控平台,没法直接可视化的看到JVM各个区域的内存变化,GC次数和GC耗时。

当然,如果有办法的话,我建议大家可以给自己所在公司推荐一下类似Zabbix、Ganglia、Open-Falcon、Prometheus之类的可视化监控平台,其实接入都非常简单,如果把线上系统接入了这些平台,可以直接图形化看到JVM的表现。

但是哪怕你有了可视化监控平台,有时候直接对线上系统进行分析的时候,还是jstat更加好用和直接。

OK,具体如何通过 jstat工具进行数据分析和打印,请查看或回顾:28-虚拟机性能监控&故障处理工具

jstat排查后的数据统计

  • 机器配置:2核4G
  • JVM堆内存大小:2G
  • 系统运行时间:3天
  • 系统运行3天内发生的Full GC次数和耗时:125次,30多秒
  • 系统运行3天内发生的Young GC次数和耗时:1.3万次,700秒

该系统通过jstat工具监测三天后得到的数据统计如上,我们发现基本上每天就会发生40多次Full GC,每一个小时大概2次Full GC,每次Full GC耗时300ms左右; 每天发生4000多次Yong GC,基本每分钟就发生3次,每次GC 50ms左右。

根据以上数据分析我们可以看出这个系统的性能是相当的差了,不管是Yong GC还是Full GC的频率太频繁了!必须进行优化。

未优化前的线上JVM参数

下面是未优化前的线上JVM参数,大致如下:

-Xms1536M -Xmx1536M -Xmn512M -Xss256K 
-XX:SurvivorRatio=5 -XX:+UseParNewGC 
-XX:+UseConcMarkSweepGC 
-XX:CMSInitiatingOccupancyFraction=68
-XX:+CMSParallelRemarkEnabled 
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC

可以看到,4G的机器,给JVM内存分配了1.5G,新生代分配了512M,老年代1G。

这里关键的是“-XX:SurvivorRatio”设置为了5,也就是说,Eden:Survivor1:Survivor2的比例是5:1:1。

那么可以推出:Eden区域大致为 366M,每个Survior区域大致为 70M。

如下图所示:

系统运行推导

1.新生代每秒分配对象的大小

由之前的统计分析可知:每分钟3次Yong GC,那么大概20s就会发生一次Yong GC,那么也就是20秒Eden区域基本就满了,20S共产生300多MB的对象,每秒大概产生 20MB的对象进Eden.

2.老年代分配对象时间
每一个小时大概2次Full GC,那么半小时就是一个Full GC,要想触发Full GC,需要达到老年代触发的阈值,而上述JVM参数中有一个

-XX:CMSInitiatingOccupancyFraction=68

参数的设置,那么也就是老年代空间大概在达到600多MB的时候就直接触发Full GC了。

总结下如下图所示:

那么分析到这儿,可能有多同学就会立马给出解决方案了:

  • 换机器:换成4核8G
  • 增大Survior区域的大小

请注意:并不是所有的问题都是可以通过增大机器内存,增大JVM内存,增大新生代内存,增大Survior区域大小就可以解决了,我们一定要先分析清楚到底是什么原因导致我们的系统会发生卡顿,是不是由于我们自己的代码问题所导致? 特别是在机器内存小的物理机上更容易检测出来我们代码的质量问题,这类问题如果不解决,而是一味的增大机器内存,根本是解决不了本质问题的!

这里真正的Full GC是真的由于Survior区域太小,导致每次Yong GC后剩余存活对象直接进入到了老年代?

还是有很多长时间存活对象,始终存活在老年代,导致无法回收?加上老年代触发Full GC的阈值只有68%,导致速度更快?

分析到这里,绝不能轻易草率的给出结论和解决方案!

那么我们到底应该如何继续分析以及排查问题,请大家积极思考可以在我们的技术交流群中给出自己的答案和分析计划。我们下篇文章再继续给出问题所在和解决方案。

目录
相关文章
|
1月前
|
SQL 存储 测试技术
SQL在构建系统中的应用:关键步骤与技巧
在构建基于数据库的应用系统时,SQL(Structured Query Language)作为与数据库交互的核心语言,扮演着至关重要的角色
|
1月前
|
数据采集 机器学习/深度学习 数据可视化
构建高效数据分析系统的关键技术
【10月更文挑战第5天】构建高效数据分析系统的关键技术
39 0
|
10天前
|
SQL 数据挖掘 Python
数据分析编程:SQL,Python or SPL?
数据分析编程用什么,SQL、python or SPL?话不多说,直接上代码,对比明显,明眼人一看就明了:本案例涵盖五个数据分析任务:1) 计算用户会话次数;2) 球员连续得分分析;3) 连续三天活跃用户数统计;4) 新用户次日留存率计算;5) 股价涨跌幅分析。每个任务基于相应数据表进行处理和计算。
|
1月前
|
SQL 存储 数据库
SQL在构建系统中的应用:关键要素与编写技巧
在构建基于数据库的系统时,SQL(Structured Query Language)扮演着至关重要的角色
|
2月前
|
SQL 存储 UED
系统里这个同时查冷热表的sql,动动手指,从8s降到3s
系统将交易数据按交易时间分为热表(最近3个月)和冷表(3个月前)。为保证用户体验,当企业门户端查询跨越冷热表时,尤其针对大客户,查询性能优化至关重要。以下是程序的SQL查询语句及其优化版本。
34 1
|
1月前
|
SQL 数据库连接 数据库
管理系统中的Visual Studio与SQL集成技巧与方法
在现代软件开发和管理系统中,Visual Studio(VS)作为强大的集成开发环境(IDE),与SQL数据库的紧密集成是构建高效、可靠应用程序的关键
|
1月前
|
SQL 监控 数据库
管理系统VS SQL:高效集成的关键技巧与方法
在现代企业信息化建设中,管理系统(如ERP、CRM等)与SQL数据库之间的紧密集成是确保数据流动顺畅、业务逻辑高效执行的关键
|
3月前
|
SQL 数据挖掘
7张图总结:SQL 数据分析常用语句!
7张图总结:SQL 数据分析常用语句!
|
3月前
|
前端开发 Java JSON
Struts 2携手AngularJS与React:探索企业级后端与现代前端框架的完美融合之道
【8月更文挑战第31天】随着Web应用复杂性的提升,前端技术日新月异。AngularJS和React作为主流前端框架,凭借强大的数据绑定和组件化能力,显著提升了开发动态及交互式Web应用的效率。同时,Struts 2 以其出色的性能和丰富的功能,成为众多Java开发者构建企业级应用的首选后端框架。本文探讨了如何将 Struts 2 与 AngularJS 和 React 整合,以充分发挥前后端各自优势,构建更强大、灵活的 Web 应用。
58 0
|
3月前
|
SQL 数据挖掘 关系型数据库

热门文章

最新文章