当前位置: 首页 > 科技观察

CPU飙升,如何排查系统性能问题?

时间:2023-03-22 01:05:13 科技观察

我在压力测试时或多或少收到过高CPU或负载警报。如果是零星出现在单机上,往往被认为是“主机抢占导致”。真的是这样吗?是什么原因造成的?这些指标在飙升吗?网络、磁盘还是高并发?可以用什么工具定位?TOP,PS还是vmstat?CPUhigh&Loadhigh和CPUlow&Loadhigh,不同的表示代表什么?一、背景知识LINUX进程状态在LINUX2.6以后的内核中,进程的基本状态一般有7种:D-不可中断睡眠、R-可执行、S-可中断睡眠、T-暂停、T-跟踪、X-死亡、Z-zombie这些状态在ps命令中都有相应的解释。D(TASK_UNINTERRUPTIBLE),不可中断的休眠状态。顾名思义,处于该状态的进程处于休眠状态,不允许被其他进程或中断(异步信号)打断。所以这个状态的进程是不能用kill-9杀死的(kill也是一个信号),除非重启系统(是的,就是这么辛苦)。但这种状态一般是由I/O等待(如磁盘I/O、网络I/O、外设I/O等)引起的,并且发生的时间很短,而且大部分很难被PS或TOP命令捕获(除非I/OHANG死掉)。处于SLEEP状态的进程不占用任何CPU资源。R(TASK_RUNNING),可执行状态。处于这种状态的进程都位于CPU的可执行队列中,正在运行或等待运行,即它们要么在工作途中,要么在工作途中。S(TASK_INTERRUPTIBLE),可以中断休眠状态。与D不同的是,这个状态的进程虽然也在休眠,但是允许被中断。这种进程一般是在等待某个事件(如socket连接、信号量等)的发生,而被挂起。一旦这些时间完成,进程将被唤醒到R状态。系统中的大部分进程都处于S状态,除非是在高负载时期。处于SLEEP状态的进程不占用任何CPU资源。T&t(__TASK_STOPPED&__TASK_TRACED),暂停或跟踪状态。这两种状态的进程都处于runningstop状态。不同的是,暂停状态一般是因为收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOUT这四个信号而停止,而trace状态则是因为进程正在被另一个进程跟踪(比如gdb断点)。暂停的进程释放所有占用的资源。Z(EXIT_ZOMBIE),僵尸状态。这个状态的进程其实已经结束了,但是父进程还没有回收它的资源(比如进程描述符、PID等)。僵尸进程释放除进程入口之外的所有资源。X(EXIT_DEAD),死亡状态。进程的真实结束状态,通常不会在正常系统中捕获。LoadAverage&CPUusage说到系统性能,Load和CPUusage是最直观的两个指标,那么这两个指标是怎么计算出来的呢?它们彼此相等吗?LoadAverage很多人都认为Load代表CPU上正在运行&等待运行的进程数,也就是,但是在Linux系统中,这个描述并不完全准确。下面是Linux内核源码中的LoadAverage计算方法。可以看出,除了可执行态进程外,不可中断的睡眠态进程也会被计算在内,即:602staticunsignedlongcount_active_tasks(void)603{604structtask_struct*p;605unsignedlongnr=0;606607read_lock(&tasklist_lock);608for_each_task(p){609if((p->state==TASK_RUNNING610(p->state&TASK_UNINTERRUPTIBLE)))611nr+=FIXED_1;612}613read_unlock(&tasklist_lock);614returnnr;615}inloadvoidstatic7(unsigned2sknedlongsactive);/*定点*/628staticintcount=LOAD_FREQ;629630count-=ticks;631if(count<0){632count+=LOAD_FREQ;633active_tasks=count_active_tasks();634CALC_LOAD(EXPven_task[1,active]);635CALC_LOAD(avenrun[1],EXP_5,active_tasks);636CALC_LOAD(avenrun[2],EXP_15,active_tasks);637}638}前面Linux进程状态中提到,休眠状态的进程不能被中断(TASK_UNINTERRUTED)一般I/O等待,例如磁盘、网络或其他外围设备。由此我们可以看出,LoadAverage反映了Linux中系统的整体负载,即CPU负载+磁盘负载+网络负载+其他外设负载,并不完全等同于CPU使用率(这只出现在Linux其他系统中,如作为Unix,Load仍然只代表CPU负载)。CPU使用率CPU时间分片一般可以分为4类:用户进程运行时间-UserTime、系统内核运行时间-SystemTime、空闲时间-IdleTime、抢占时间-StealTime。除空闲时间外,其余时间CPU都处于工作状态。一般来说,我们一般所指的整体CPU使用率是UserTime和Systime(比如tsar中的CPUutil)的总和,即大多数性能统计工具为了方便定位问题,将这四种类型进一步细化oftimeslices转化成了8类。下面是按照TOP对CPU时间片的分类。us:用户进程空间中优先级不变的进程占用的CPU百分比sy:内核空间占用的CPU百分比ni:用户进程空间中优先级改变的进程占用的CPU百分比id:空闲时间百分比wa:idle&waitingforI/O'stimepercentagehi:硬中断时间百分比si:软中断时间百分比st:虚拟化过程中被其他VM窃取的时间百分比8种切片中,除wa和id外,其余切片CPU处于工作状态。2Resource&BottleneckAnalysis从上面我们了解到LoadAverage和CPUusage可以细分为不同的子域指标,指向不同的资源瓶颈。总的来说,指标与资源瓶颈的对应关系基本如下图所示。HighLoad&HighCPU这是我们最常遇到的情况,即CPU负载增加导致负载增加。根据CPU具体的资源分配性能,可以分为以下几类:CPUsyshigh。在这种情况下,主要的CPU开销在于系统内核。可以进一步查看上下文切换情况。如果非自愿的上下文切换较多,说明CPU抢占比较激烈,大量进程由于时间片等原因被系统强制调度,进而发生上下文切换。如果自愿上下文切换的次数较多,说明可能存在I/O、内存等系统资源瓶颈,大量进程无法获取所需资源,从而导致上下文切换。CPUsi高。在这种情况下,大量的CPU消耗在软中断上。您可以进一步检查软中断类型。一般来说,由网络I/O或线程调度引起的软中断是最常见的:NET_TX&NET_RX。NET_TX是发送网络数据包的软中断,NET_RX是接收网络数据包的软中断。当两种类型的软中断都很高时,系统更容易出现网络I/O瓶颈。预定。SCHED是指进程调度和负载均衡引起的中断。当此类中断较多时,系统中进程切换较多,一般与非自愿上下文切换同时发生,可能会出现CPU瓶颈。如果CPUus高,说明资源主要被应用进程消耗。可能的原因有:代码死循环或CPU密集型计算。在这种情况下,多核CPUus会同时上升。内存问题,导致大量FULLGC,阻塞线程。在这种情况下,只有一个核心CPUus增加了。资源等待导致线程池满,进而导致CPU上升。这种情况下,会同时出现threadpoolfull等异常。出现highLoad&lowCPU情况的根本原因是有很多进程处于不间断睡眠状态(TASK_UNINTERRUPTIBLE),即CPU负载不高,但I/O负载高。可以进一步定位是磁盘I/O引起的还是网络I/O引起的。三种故障排除策略使用现有的常用工具。我们常用的排查策略基本如下图所示:从发现问题到最终定位,基本上可以分为四个阶段:资源瓶颈定位该阶段使用全局性能测试工具进行初步定位。资源消耗异常站点。常用工具有:top、vmstat、tsar(history)中断:/proc/softirqs、/proc/interruptsI/O:iostat、dstat定位热点进程,定位资源瓶颈后,可以进一步分析资源消耗具体进程和查找Hot进程。常用的工具有:上下文切换:pidstat-wCPU:pidstat-uI/O:iotop、pidstat-d僵尸进程:psthread&进程内部资源定位找到具体进程后,可以分析其内部资源开销过程详细。常用的工具有:上下文切换:pidstat-w-p[pid]CPU:pidstat-u-p[pid]I/O:lsof热点事件&方法分析反向关联,定位问题范围到具体方法&堆。常用的工具有:perf:Linux自带的性能分析工具,功能类似hotmethod,基于事件采样原理,基于性能事件,支持对处理器相关的性能指标和操作系统相关的性能进行性能分析指标。jstack可以与ps-Lp或pidstat-p结合使用来初步定位热线程。结合zprofile-threaddump,可以统计线程的分布情况,等待锁,分析线程的常用和增加情况。strace:跟踪进程执行期间的系统调用和接收到的信号。tcpdump:抓包分析,常用于网络I/O瓶颈定位。相关阅读[1]LinuxLoadAverages:解谜http://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html[2]LoadAverages到底是什么?http://linuxtechsupport.blogspot.com/2008/10/what-exactly-is-load-average.html