再一次生产-CPU-高负载排查实践

前言前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨。 其实早在去年我也处理过类似的问题,并记录下来:《一次生产 CPU 100% 排查优化实践》 不过本次问题产生的原因却和上次不太一样,大家可以接着往下看。 <!--more--> 问题分析收到邮件后我马上登陆那台服务器,看了下案发现场还在(负载依然很高)。 于是我便利用这类问题的排查套路定位一遍。 首先利用 top -c 将系统资源使用情况实时显示出来 (-c 参数可以完整显示命令)。 接着输入大写 P 将应用按照 CPU 使用率排序,第一个就是使用率最高的程序。 果不其然就是我们的一个 Java 应用。 这个应用简单来说就是定时跑一些报表使的,每天凌晨会触发任务调度,正常情况下几个小时就会运行完毕。 常规操作第二步自然是得知道这个应用中最耗 CPU 的线程到底再干嘛。 利用 top -Hp pid 然后输入 P 依然可以按照 CPU 使用率将线程排序。 这时我们只需要记住线程的 ID 将其转换为 16 进制存储起来,通过 jstack pid >pid.log 生成日志文件,利用刚才保存的 16 进制进程 ID 去这个线程快照中搜索即可知道消耗 CPU 的线程在干啥了。 如果你嫌麻烦,我也强烈推荐阿里开源的问题定位神器 arthas 来定位问题。 比如上述操作便可精简为一个命令 thread -n 3 即可将最忙碌的三个线程快照打印出来,非常高效。 更多关于 arthas 使用教程请参考官方文档。由于之前忘记截图了,这里我直接得出结论吧: ...

June 18, 2019 · 1 min · jiezi

什么会导致Java应用程序的CPU使用率飙升

问题无限循环的while会导致CPU使用率飙升吗?经常使用Young GC会导致CPU占用率飙升吗?具有大量线程的应用程序的CPU使用率是否较高?CPU使用率高的应用程序的线程数是多少?处于BLOCKED状态的线程会导致CPU使用率飙升吗?分时操作系统中的CPU是消耗us还是sy?思路1.如何计算CPU使用率?CPU%= 1 - idleTime / sysTime * 100 idleTime:CPU空闲的时间sysTime:CPU处于用户模式和内核模式的时间总和2.与CPU使用率有关的是什么?人们常说,计算密集型程序的CPU密集程度更高。 那么,JAVA应用程序中的哪些操作更加CPU密集? 以下列出了常见的CPU密集型操作: 频繁的GC; 如果访问量很高,可能会导致频繁的GC甚至FGC。当调用量很大时,内存分配将如此之快以至于GC线程将连续执行,这将导致CPU飙升。序列化和反序列化。稍后将给出一个示例:当程序执行xml解析时,调用量会增加,从而导致CPU变满。序列化和反序列化;正则表达式。 我遇到了正则表达式使CPU充满的情况; 原因可能是Java正则表达式使用的引擎实现是NFA自动机,它将在字符匹配期间执行回溯。我写了一篇文章“ 正则表达式中的隐藏陷阱 ”来详细解释原因。线程上下文切换; 有许多已启动的线程,这些线程的状态在Blocked(锁定等待,IO等待等)和Running之间发生变化。当锁争用激烈时,这种情况很容易发生。有些线程正在执行非阻塞操作,例如while (true)语句。如果在程序中计算需要很长时间,则可以使线程休眠。3. CPU是否与进程和线程相关?现在,分时操作系统使用循环方式为进程调度分配时间片。如果进程正在等待或阻塞,那么它将不会使用CPU资源。线程称为轻量级进程,并共享进程资源。因此,线程调度在CPU中也是分时的。但在Java中,我们使用JVM进行线程调度。因此,通常,线程调度有两种模式:时间共享调度和抢占式调度。 答案1. while的无限循环会导致CPU使用率飙升吗?是。 首先,无限循环将调用CPU寄存器进行计数,此操作将占用CPU资源。那么,如果线程始终处于无限循环状态,CPU是否会切换线程? 除非操作系统时间片到期,否则无限循环不会放弃占用的CPU资源,并且无限循环将继续向系统请求时间片,直到系统没有空闲时间来执行任何其他操作。 stackoverflow中也提出了这个问题:为什么无意的无限循环增加了CPU的使用? https://stackoverflow.com/questions/2846165/why-does-an-infinite-loop-of-the-unintended-kind-increase-the-cpu-use 2.频繁的Young GC会导致CPU占用率飙升吗?是。 Young GC本身就是JVM用于垃圾收集的操作,它需要计算内存和调用寄存器。因此,频繁的Young GC必须占用CPU资源。 让我们来看一个现实世界的案例。for循环从数据库中查询数据集合,然后再次封装新的数据集合。如果内存不足以存储,JVM将回收不再使用的数据。因此,如果所需的存储空间很大,您可能会收到CPU使用率警报。 3.具有大量线程的应用程序的CPU使用率是否较高?不时。 如果通过jstack检查系统线程状态时线程总数很大,但处于Runnable和Running状态的线程数不多,则CPU使用率不一定很高。 我遇到过这样一种情况:系统线程的数量是1000+,其中超过900个线程处于BLOCKED和WAITING状态。该线程占用很少的CPU。 但是大多数情况下,如果线程数很大,那么常见的原因是大量线程处于BLOCKED和WAITING状态。 4.对于CPU占用率高的应用程序,线程数是否较大?不是。 高CPU使用率的关键因素是计算密集型操作。如果一个线程中有大量计算,则CPU使用率也可能很高。这也是数据脚本任务需要在大规模集群上运行的原因。 5.处于BLOCKED状态的线程是否会导致CPU占用率飙升?不会。 CPU使用率的飙升更多是由于上下文切换或过多的可运行状态线程。处于阻塞状态的线程不一定会导致CPU使用率上升。 6.如果分时操作系统中CPU的值us或sy值很高,这意味着什么?您可以使用命令查找CPU的值us和sy值top,如以下示例所示: us:用户空间占用CPU的百分比。简单来说,高我们是由程序引起的。通过分析线程堆栈很容易找到有问题的线程。sy:内核空间占用CPU的百分比。当sy为高时,如果它是由程序引起的,那么它基本上是由于线程上下文切换。经验如何找出CPU使用率高的原因?下面简要描述分析过程。 如果发现应用程序服务器的CPU使用率很高,请首先检查线程数,JVM,系统负载等参数,然后使用这些参数来证明问题的原因。其次,使用jstack打印堆栈信息并使用工具分析线程使用情况(建议使用fastThread,一个在线线程分析工具)。 以下是一个真实案例: 一天晚上,我突然收到一条消息,说CPU使用率达到了100%。所以立即,我倾倒了用jstack打印的堆栈信息。 进一步检查日志: onsumer_ODC_L_nn_jmq919_1543834242875 - priority:10 - threadid:0x00007fbf7011e000 - nativeid:0x2f093 - state:RUNNABLEstackTrace:java.lang.Thread.State:RUNNABLEat java.lang.Object.hashCode(Native Method)at java.util.HashMap.hash(HashMap.java:362)at java.util.HashMap.getEntry(HashMap.java:462)at java.util.HashMap.containsKey(HashMap.java:449)at com.project.order.odc.util.XmlSerializableTool.deSerializeXML(XMLSerializableTool.java:100)at com.project.plugin.service.message.resolver.impl.OrderFinishMessageResolver.parseMessage(OrderFinishMessageResolver.java:55)at com.project.plugin.service.message.resolver.impl.OrderFinishMessageResolver.parseMessage(OrderFinishMessageResolver.java:21)at com.project.plugin.service.message.resolver.impl.AbstractResolver.resolve(AbstractResolver.java:28)at com.project.plugin.service.jmq.AbstractListener.onMessage(AbstractListener.java:44)现在通过这个日志找到了问题:用于反序列化MQ消息实体的方法导致CPU使用率飙升。 ...

May 24, 2019 · 1 min · jiezi

Visual Studio Code使用中CPU占用率异常暴增过高原因

今天要说的是一个困扰我好几个月的问题,Visual Studio Code(下文简称VSCode)在使用中突然增高,风扇开始狂转,温度骤增,影响心情的故障原因。其实,无论是Windows还是OSX,很多人可能或多或少都遇到过VSCode突然就不好使了,我就遇到过好多次疑难杂症,折腾很久才弄出来,比如下面三点:tab键突然就不好使了,卡顿很久或者压根无法缩进,并且sidebar的git那块功能彻底失效!写Markdown文档的时候,tab键的缩进只能向右,不能收回。。。这真是奇葩。使用中莫名其妙的风扇就响了起来,看看进程和温度,CPU满载执行,完全不知道怎么回事,这也是本次要专门提到的问题。系统使用环境及VSCode状态检测我使用的是黑苹果,当然这个与CPU占用率增高并无关系,通过code –status查看一些基本信息如下:P750TM:~ whidy$ code –statusVersion: Code 1.30.2 (61122f88f0bf01e2ac16bdb9e1bc4571755f5bd8, 2019-01-07T22:48:31.260Z)OS Version: Darwin x64 17.7.0CPUs: Intel(R) Core(TM) i5-8600K CPU @ 3.60GHz (6 x 3600)Memory (System): 16.00GB (5.22GB free)Load (avg): 2, 2, 2VM: 0%Screen Reader: noProcess Argv: –inspect-extensions=9993GPU Status: 2d_canvas: enabled checker_imaging: disabled_off flash_3d: enabled flash_stage3d: enabled flash_stage3d_baseline: enabled gpu_compositing: enabled multiple_raster_threads: enabled_on native_gpu_memory_buffers: enabled rasterization: unavailable_software video_decode: enabled video_encode: enabled webgl: enabled webgl2: enabledCPU % Mem MB PID Process 0 98 1775 code main 0 49 1776 gpu-process 0 229 1777 window (settings.json — mpa-stat-sdk) 0 0 1780 /bin/bash -l 0 115 1783 extensionHost 0 82 1787 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper –nolazy –inspect=10785 /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/json-language-features/server/dist/jsonServerMain –node-ipc –clientProcessId=1783 0 49 1784 watcherService 0 49 1789 searchService 0 33 1785 utility 0 82 1817 shared-process 0 311 1830 window (ald-stat.js — one-plus-sport) 0 49 1831 watcherService 0 98 1832 extensionHost 4 66 1870 electron_node eslintServer.js 0 131 1871 electron_node tsserver.js 0 66 1879 electron_node typingsInstaller.js typesMap.js 0 49 1835 searchServiceWorkspace Stats: | Window (ald-stat.js — one-plus-sport)| Window (settings.json — mpa-stat-sdk)| Folder (one-plus-sport): 273 files| File types: js(75) json(58) wxss(57) wxml(56) png(21) md(2)| gitignore(1) xlsx(1) jpg(1) zip(1)| Conf files:| Folder (mpa-stat-sdk): 21 files| File types: js(13) md(3) json(2) zip(2) gitignore(1)| Conf files: gulp.js(1) package.json(1)故障现象先来看看正常情况下和非正常情况的运行情况对比图:上图为正常情况下的截图上图为异常情况下的截图这个问题真的令我很苦恼,我这两张截图期间绝对没有做任何可能会产生高计算需求的工作,但是正常的操作怎么会出现这种情况呢。故障分析及解决于是进行了大量的搜索,百度就不用看了,屎一样的结果:前5篇内容完全一致,结论:“search.followSymlinks”:true,在我这一点用也没用。顺便吐槽,我完全不理解,在中国尤其是CSDN,为什么一个简单的小问题,一大堆人转载,完全一样的内容,如果真的是神一般的技巧,敢不敢多写一点,为什么这样能解决问题,出现故障的原因呢,无脑抄袭就算了,做笔记请使用自己的笔记本,比如有道云笔记,印象笔记不好吗,难道没人知道你是抄的?简直浪费搜索时间!垃圾!吐槽完毕,该用google了,实际上,我一开始就没用百度,只是写这篇文章,担心有人遇到过这样的问题,写过相同的解决方案,说我是抄来的。就索性百度搜一下。用谷歌自然用英文,虽然我英语很渣,但是谷歌懂我。只需要几个关键词:无论是微软官方的issue查,还是stackoverflow查,总能有很大的收获,但是,我这个问题比较特殊,我尝试过最基本的两种处理办法:屏蔽所有插件测试重置自定义的settings.json文件然而都不好使。可怜我英文也不是特别好,有可能有些有用的信息被我忽略掉了。这里补充一下,其实大部分原因,可以通过官方提供的自排除方案来检查Performance Issues,我很推荐遇到CPU占用率过高的情况下先看看这篇文章。不过也不是全无收获,至少开头提到的三个问题,前两个查出来了。第一个问题是插件Auto Rename Tag造成的,这个至少在一年前是非常流行的,我自己也觉得很好用,就一直装了,完全想不到这个简单的功能居然会造成VSCode某些功能异常,去插件主页看看,作者也不更新维护了,插件评价页面全是一星,可见目前已经是垃圾插件了查看评论,不过过年很多无脑转载的还在推荐这个插件,所以为了避免大家入坑,建议不要使用Auto Rename Tag。第二个问题也是插件问题,就是Markdown All in One这个插件导致缩进功能不好使,原因我也不知道,其实这个问题并不严重,有强烈依赖改插件的朋友还是可以继续使用,我也很推荐这个插件写markdow,有些还是挺便捷的,不过我是删了哈哈哈,看个人意愿了~好了第三个问题才是最重要的,我反复观察了很久,做了大量测试和查阅文档,终于得出结论:当且仅当VSCode的窗口大于1个的时候,才会出现该现象出现异常经常出现在切换不同窗口之后发生我发现切换窗口后出现异常就搜索关键词two/multi vscode switch cause a high cpu useage终于找到了一丝丝线索,仔细阅读了下面几篇:Switching between VSCode windows with any custom app switcher causes high CPU usageapplication processes consume 200% CPU combinedExtreme CPU usage when multiple windows are openRenderer high CPU on OSX with custom window switchers我终于,发现了一个问题,我切换VSCode的窗口的方式有问题!!!我是用了罗技鼠标的快捷键功能导致,如图:啊,我的天啊!我反复尝试,在多个窗口,直接用键盘的Cmd + 来切换内部应用窗口,妥妥的一点毛病都没有。结论很多情况下VSCode功能异常都是插件引起的,尝试关闭所有插件来检查,建议阅读Performance Issues。其次是**第三方Switcher应用切换VSCode窗口会造成异常!比如常用的鼠标功能键!啊,坑了我好多个月,反复重装VSCode和系统都没法解决的毛病终于解决了。。。以后只能用Cmd + 来切换了 ...

January 28, 2019 · 2 min · jiezi