问题查出来是这样的。最近小麦仔负责的项目定于今天凌晨2点更新版本。前几天,测试小姐姐在网站上进行了压力测试,观察了服务的CPU、内存、负载、RT、QPS等各项指标。压力测试的时候,测试小姐姐发现我们的一个接口,QPS升到400后,CPU使用率急剧上升。CPU、内存、负载、RT、QPS等我这里就不过多赘述了,毕竟讨论到这几点,一篇文章未必就完了。有兴趣进一步研究的可以自行查看。这里我只对QPS和CPU利用率做一个简单的概述。QPSqueryratepersecond,QPS是衡量特定查询服务器在指定时间内处理多少流量的指标。QPS越高,表示服务器在一定时间内处理的流量越大。CPU利用率用来描述CPU的使用情况,表示一段时间内CPU的占用情况。使用率越高,说明机器此时运行的程序很多,反之亦然。了解了这两个基本点之后,再来看看我是如何定位的。问题定位测试小姐姐报出这个问题后,我登录服务器做了如下操作:1.定位到进程登录服务器,执行top命令查看CPU使用情况:$topPIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND44529root2004289m874m13312S123.010.910:39.73javatop命令检查所有进程占用系统CPU的顺序。是Linux下常用的性能分析工具。它可以实时显示系统中各个进程的资源占用情况,类似于Windows的任务管理器。我们来看看这些指标代表什么:PID——进程idUSER——进程所有者PR——进程优先级NI——nice值。负值表示高优先级,正值表示低优先级VIRT—进程使用的虚拟内存总量,单位为kb。VIRT=SWAP+RESRES—进程使用但未换出的物理内存大小,以kb为单位。RES=CODE+DATASHR——共享内存大小,单位kbS——进程状态。D=不间断睡眠状态R=runningS=sleepT=trace/stopZ=zombieprocess%CPU—自上次更新以来的CPU时间百分比%MEM—进程使用的物理内存百分比TIME+—进程使用的CPU总时间,unit1/100secondCOMMAND--进程名(命令名/命令行)通过执行top命令可以看到进程ID为44529的Java进程CPU使用率达到了123%,基本可以定位为我们的Java应用导致整个服务器的CPU使用率飙升。2.定位线程当然Java是单进程多线程的。接下来我查看了这个PID=44529的Java进程中各个线程的CPU使用情况,同样使用了top命令:$top-Hp44529PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND44580root2004289m874m13312S16.210.93:02.96java通过执行top-Hp44529命令,发现在44529进程中,ID为44580的线程CPU占用率最高。3.定位代码通过top命令,我定位到了具体导致CPU占用率高的线程。接下来,我需要查看哪一行代码有问题。首先,我将线程44580转换成十六进制:$printf%x44580ae24接下来,根据十六进制值在打印的堆栈日志中查询,查看线程所在方法的位置。并通过jstack命令查看堆栈信息:$jstack44529|grep-A200ae24"SystemClock"#28daemonprio=5os_prio=0tid=0x00007efc19e8e800nid=0xae24waitingoncondition[0x00007efbe0d91000]java.lang.Thread。状态:TIMED_WAITING(睡眠)在java.lang.Thread.sleep(本机方法)在java.lang.Thread.sleep(Thread.java:340)在java.util.concurrentC.TimeUnit.sleep(TimeUnit.java:386)atcom.*.order.Controller.OrderController.detail(OrderController.java:37)//业务代码阻塞点通过上面的代码,我们可以清楚的看到OrderController.java的第37行可能存在问题。然后在项目中找到OrderController.java的第37行,仔细分析后发现由于自己的粗心,导致代码存在逻辑漏洞。修改重构后,问题解决。综上所述,以上就是解决该问题的全过程。主要用到的有:top、printf、jstack等指令。使用top命令查看当前占用CPU高的进程PID;查看当前进程消耗资源的线程PID:top-HpPID将线程PID转为16进制,根据16进制值在打印的栈日志中查询,可以查看该线程所在的方法位置。通过jstack命令查看堆栈信息。这一步基本上已经能定位到大部分问题了。算算年项目于今天凌晨2点启动。我昨晚加班了。早上回到家,我只睡了两个小时。隔壁邻居开始装修,墙又钻又砸,又裂又撞,吵得我睡不着觉(感觉??已经快要猝死了)。于是起身写了这篇文章,也算是记录了2020年的第一篇加班。最后感谢大家的阅读。文章的目的是记录和分享。如果文章中有明显的错误,欢迎大家指出。让我们在讨论中共同学习。太好了!如果您觉得本文对您有用,请点个赞。你们的鼓励和支持,是我前进的动力~欢迎关注我的微信公众号[小麻子],我们一起讨论代码,讨论生活。
