如何快速分析Linux服务器的性能问题

更新时间:02-02 教程 由 留井 分享

当遇到一个系统性能问题时,如何利用登录的前60秒对系统的性能情况做一个快速浏览和分析,主要包括如下10个工具,这是一个非常有用且有效的命工具列表。本文将详细介绍这些命令及其扩展选项的意义,及其在实践中的作用。并利用一个实际出现问题的例子,来验证这些套路是不是可行,下面工具的屏幕输出结果都来自这个出现题的系统。

#系统负载概览uptime

#系统日志dmesg|tail

#CPUvmstat1mpstat-PALL1pidstat1

#Diskiostat-xz1

#内存free-m

#网络sar-nDEV1sar-nTCP,ETCP1

#系统概览top

上面的工具都基于内核提供给用户态的统计,并以计数器形式展示,是快速排查时的利器。对于应用和系统的进一步跟踪(tracing),则需要利用strace和systemtap,不在本文的范畴。

注意:

如上的分类只是基于工具默认选项的分类,比如pidstat,默认展示进程的CPU统计,但是利用-d参数可以展示进程的I/O统计。又比如vmstat,虽然名称是查看虚拟内存的工具,但默认展示了负载,内存,I/O,系统,CPU等多方面的信息。部分工具需要安装sysstat包。

1.uptime[root@nginx1~]#uptime15:38:10up43days,3:54,1user,loadaverage:1.13,0.41,0.18

uptime是快速查看loadaverage的方法,在Linux中loadaverage包括处于runnable和uninterruptable状态的进程总数,runnable状态的进程包括在CPU上运行的进程和已经readytorun在等待CPU时间的进程;uninterruptable状态的进程是在等待一些I/O访问,比如等待disk的返回。Loadaverage没有根据系统的CPU数量做格式化,所以loadaverage1表示单CPU系统在对应时间段内(1分钟,5分钟,15分钟)一直负载饱和,而在4CPU的系统中,loadaverage1表示有75%的时间在idle。

Loadaverage体现了一个highlevel的负载概览,但是可能需要和别的工具一起来使用以了解更多信息,比如处于runable和uninterruptable的实时进程数量分别是多少,可以用下面将介绍到的vmstat来查看。1分钟,5分钟,15分钟的负载平均值同时能体现系统负载的变化情况。例如,如果你要检查一个问题服务器,当你看到1分钟的平均负载值已经远小于15分钟的平均负载值,则意味这也许你登录晚了点,错过了现场。用top或者w命令,也可以看到loadaverage信息。

上面示例中最近1分钟内的负载比15分钟内的负载高了不少(因为是个测试的例子,1.13可以看作明显大于0.18,但是在生产系统上这不能说明什么)。

2.dmesg|tail

[root@nginx1~]#dmesg|tail[3128052.929139]deviceeth0leftpromiscuousmode[3128104.794514]deviceeth0enteredpromiscuousmode[3128526.750271]deviceeth0leftpromiscuousmode[3537292.096991]deviceeth0enteredpromiscuousmode[3537295.941952]deviceeth0leftpromiscuousmode[3537306.450497]deviceeth0enteredpromiscuousmode[3537307.884028]deviceeth0leftpromiscuousmode[3668025.020351]bash(8290):drop_caches:1[3674191.126305]bash(8290):drop_caches:2[3675304.139734]bash(8290):drop_caches:1

dmesg用于查看内核缓冲区存放的系统信息。另外查看/var/log/messages也可能查看出服务器系统方面的某些问题。

上面示例中的dmesg没有特别的值得注意的错误。

3.vmstat1

vmstat简介:

vmstat是virtualmemorystat的简写,能够打印processes,memory,paging,blockIO,traps,disksandcpu的相关信息。vmstat的格式:vmstat[options][delay[count]]。在输入中的1是延迟。第一行打印的是机器启动到现在的平均值,后面打印的则是根据deley间隔的取样结果,也就是实时的结果。

结果中列的含义:

Procs(进程)

r:Thenumberofrunnableprocesses(runningorwaitingforruntime).b:Thenumberofprocessesinuninterruptiblesleep.

注释:r表示在CPU上运行的进程和ready等待运行的进程总数,相比loadaverage,这个值更能判断CPU是否饱和(saturation),因为它没有包括I/O。如果r的值大于CPU数目,即达到饱和。

Memory

swpd:theamountofvirtualmemoryused.free:theamountofidlememory.buff:theamountofmemoryusedasbuffers.cache:theamountofmemoryusedascache.

Swap

si:Amountofmemoryswappedinfromdisk(/s).so:Amountofmemoryswappedtodisk(/s).

注释:swap-in和swap-out的内存。如果是非零,说明主存中的内存耗尽。

IO

bi:Blocksreceivedfromablockdevice(blocks/s).bo:Blockssenttoablockdevice(blocks/s).

System(中断和进程上下文切换)

in:Thenumberofinterruptspersecond,includingtheclock.cs:Thenumberofcontextswitchespersecond.

CPU

ThesearepercentagesoftotalCPUtime.us:Timespentrunningnon-kernelcode.(usertime,includingnicetime)sy:Timespentrunningkernelcode.(systemtime)id:Timespentidle.PriortoLinux2.5.41,thisincludesIO-waittime.wa:TimespentwaitingforIO.PriortoLinux2.5.41,includedinidle.st:Timestolenfromavirtualmachine.PriortoLinux2.6.11,unknown.

根据user+system时间,可以判断CPUs是否繁忙。如果waitI/O一直维持一定程度,说明disk有瓶颈,这时CPUs是"idle"的,因为任务都被block在等待diskI/O中。waitI/O可以被视为另一种形式的CPUidle,并且说明idle的原因就是在等待diskI/O的完成。

处理I/O需要花费systemtime,在将I/O提交到diskdriver之前可能要经过remap,split和merge等操作,并被I/Oscheduler调度到requestqueue。如果处理I/O时平均systemtime比较高,超过20%,则要进一步分析下,是不是内核处理I/O时的效率有问题。

如果用户空间的CPU使用率接近100%,不一定就代表有问题,可以结合r列的进程总数量看下CPU的饱和程度。

上面示例可以看到在CPU方面有一个明显的问题。user+system的CPU一直维持在50%左右,并且system消耗了大部分的CPU。

4.mpstat-PALL1

mpstat可以打印按照CPU的分解,可以用来检查不不均衡的情况。

上面示例结果可以印证vmstat中观察到的结论,并且可以看到服务器有2个CPU,其中CPU1的使用率一直维持在100%,而CPU0并没有什么负载。CPU1的消耗主要在内核空间,而非用户空间。

5.pidstat1

默认pidstat类似于top按照进程的打印方式,不过是以滚动打印的方式,和top的清屏方式不同。利用-p可以打出指定进程的信息,-pALL可以打出所有进程的信息。如果没有指定任何进程默认相当于-pALL,但是只打印活动进程的信息(统计非0的数据)。

pidstat不只可以打印进程的CPU信息,还可以打印内存,I/O等方面的信息,如下是比较有用的信息:

pidstat-d1:看哪些进程有读写。pidstat-r1:看进程的pagefault和内存使用。没有发生pagefault的进程默认不会被打印出来,可以指定-p和进程号来打印查看内存。pidstat-t:利用-t查看线程信息,可以快速查看线程和期相关线程的关系。pidstat-w:利用-w查看进程的contextswitch情况。输出:cswch/s:每秒发生的voluntarycontextswitch数目(voluntarycs:当进程被block在获取不到的资源时,主动发生的contextswitch)nvcswch/s:每秒发生的nonvoluntarycontextswitch数目(nonvloluntarycs:进程执行一段时间用完了CPU分配的timeslice,被强制从CPU上调度下来,这时发生的contextswitch)

上面示例中可以明确得看到是nc这个进程在消耗CPU1100%的CPU。因为测试系统里消耗CPU的进程比较少,所以一目了然,在生产系统中pidstat应该能输出更多正在消耗CPU的进程情况。

6.iostat-zx1

了解块设备(blockdevice,这里是disk)负载和性能的工具。主要看如下指标:

r/s,w/s,rkB/s,wkB/s:每秒完成的读请求次数(readrequests,aftermerges),每秒完成的写请求次数(writerequestscompleted,aftermerges),每秒读取的千字节数,每秒写入的千字节数。这些指标可以看出disk的负载情况。一个性能问题可能仅仅是因为disk的负载过大。await:每个I/O平均所需的时间,单位为毫秒。await不仅包括硬盘设备处理I/O的时间,还包括了在kernel队列中等待的时间。要精确地知道块设备service一个I/O请求地时间,可供iostat读取地内核统计并没有体现,需要用如blktrace这样地跟踪工具来跟踪。对于blktrace来说,D2C的时间间隔代表硬件块设备地servicetime,Q2C代表整个I/O请求所消耗的时间,即iostat的await。avgqu-sz:队列里的平均I/O请求数量(更恰当的理解应该是平均未完成的I/O请求数量)。如果该值大于1,则有饱和的趋势(当然设备可以并发地处理请求,特别是一个front对多个backenddisk的虚拟设备)。%util:设备在处理I/O的时间占总时间的百分比。表示该设备有I/O(即非空闲)的时间比率,不考虑I/O有多少,只考虑有没有。通常该指标达到60%即可能引起性能问题(可以根据await指标进一步求证)。如果指标接近100%,通常就说明出现了饱和。

如果存储设备是一个对应多个后端磁盘的逻辑磁盘,那么100%使用率可能仅仅表示一些I/O在处理时间占比达到100%,其他后端磁盘不一定也到达了饱和。请注意磁盘I/O的性能问题并不一定会造成应用的问题,很多技术都是使用异步I/O操作,所以应用不一定会被block或者直接受到延迟的影响。

7.free-m#free-mtotalusedfreesharedbuff/cacheavailableMem:7822129214074787371Swap:000

查看内存使用情况。倒数第二列:

buffers:buffercache,用于blockdeviceI/O。cached:pagecache,用于文件系统。

Linux用freememory来做cache,当应用需要时,这些cache可以被回收。比如kswapd内核进程做页面回收时可能回收cache;另外手动写/proc/sys/vm/drop_caches也会导致cache回收。

上面示例中free的内存只有129M,大部分memory被cache占用。但是系统并没有问题。

8.sar-nDEV1

输出指标的含义如下:

rxpck/s:Totalnumberofpacketsreceivedpersecond.txpck/s:Totalnumberofpacketstransmittedpersecond.rxkB/s:Totalnumberofkilobytesreceivedpersecond.txkB/s:Totalnumberofkilobytestransmittedpersecond.rxcmp/s:Numberofcompressedpacketsreceivedpersecond(forcslipetc.).txcmp/s:Numberofcompressedpacketstransmittedpersecond.rxmcst/s:Numberofmulticastpacketsreceivedpersecond.%ifutil:Utilizationpercentageofthenetworkinterface.Forhalf-duplexinterfaces,utilizationiscalculatedusingthesumofrxkB/sandtxkB/sasapercentageoftheinterfacespeed.Forfull-duplex,thisisthegreaterofrxkB/SortxkB/s.

这个工具可以查看网络接口的吞吐量,特别是上面蓝色高亮的rxkB/s和txkB/s,这是网络负载,也可以看是否达到了limit。

9.sar-nTCP,ETCP1

输出指标的含义如下:

active/s:ThenumberoftimesTCPconnectionshavemadeadirecttransitiontotheSYN-SENTstatefromtheCLOSEDstatepersecond[tcpActiveOpens].passive/s:ThenumberoftimesTCPconnectionshavemadeadirecttransitiontotheSYN-RCVDstatefromtheLISTENstatepersecond[tcpPassiveOpens].iseg/s:Thetotalnumberofsegmentsreceivedpersecond,includingthosereceivedinerror[tcpInSegs].Thiscountincludessegmentsreceivedoncurrentlyestablishedconnections.oseg/s:Thetotalnumberofsegmentssentpersecond,includingthoseoncurrentconnectionsbutexcludingthosecontainingonlyretransmittedoctets[tcpOutSegs].atmptf/s:ThenumberoftimespersecondTCPconnectionshavemadeadirecttransitiontotheCLOSEDstatefromeithertheSYN-SENTstateortheSYN-RCVDstate,plusthenumberoftimespersecondTCPconnectionshavemadeadirecttransitiontotheLISTENstatefromtheSYN-RCVDstate[tcpAttemptFails].estres/s:ThenumberoftimespersecondTCPconnectionshavemadeadirecttransitiontotheCLOSEDstatefromeithertheESTABLISHEDstateortheCLOSE-WAITstate[tcpEstabResets].retrans/s:Thetotalnumberofsegmentsretransmittedpersecond-thatis,thenumberofTCPsegmentstransmittedcontainingoneormorepreviouslytransmittedoctets[tcpRetransSegs].isegerr/s:Thetotalnumberofsegmentsreceivedinerror(e.g.,badTCPchecksums)persecond[tcpInErrs].orsts/s:ThenumberofTCPsegmentssentpersecondcontainingtheRSTflag[tcpOutRsts].

上述蓝色高亮的3个指标:active/s,passive/s和retrans/s是比较有代表性的指标。

active/s和passive/s分别是本地发起的每秒新建TCP连接数和远程发起的TCP新建连接数。这两个指标可以粗略地判断服务器的负载。可以用active衡量出站发向,用passive衡量入站方向,但也不是完全准确(比如,考虑localhost到localhost的连接)。retrans是网络或者服务器发生问题的象征。有可能问题是网络不稳定,比如Internet网络问题,或者服务器过载丢包。

10.top

#topTasks:79total,2running,77sleeping,0stopped,0zombie%Cpu(s):6.0us,44.1sy,0.0ni,49.6id,0.0wa,0.0hi,0.3si,0.0stKiBMem:8010456total,7326348free,132296used,551812buff/cacheKiBSwap:0total,0free,0used.7625940availMemPIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND4617root2004406420761544R100.00.016:27.23nc13634nginx20012119238641208S0.30.017:59.85nginx1root20012537237402428S0.00.06:11.53systemd2root200000S0.00.00:00.60kthreadd3root200000S0.00.00:17.92ksoftirqd/05root0-20000S0.00.00:00.00kworker/0:0H7rootrt0000S0.00.00:03.21migration/08root200000S0.00.00:00.00rcu_bh9root200000S0.00.031:47.62rcu_sched10rootrt0000S0.00.00:10.00watchdog/0

top是一个常用的命令,包括了多方面的指标。缺点是没有滚动输出(rollingoutput),不可复现问题发生时不容易保留信息。对于信息保留,用vmstat或者pidstat等能够提供滚动输出的工具会更好。

示例的问题?

在上面利用工具排查的过程中,我们可以在非常短的时间内快速得到如下结论:

2个CPU,nc这个进程消耗了CPU1100%的时间,并且时间消耗在system内核态。其他进程基本没有在消耗CPU。内存free比较少,大部分在cache中(并不是问题)。DiskI/O非常低,平均读写请求小于1个。收到报文在个位数KB/s级别,每秒有15个被动建立的TCP连接,没有明显异常。

整个排查过程把系统的问题定位到了进程级别,并且能排除一些可能性(DiskI/O和内存)。接下来就是进一步到进程级别的排查,不属于本文的覆盖范围,有时间再进一步演示。

声明:关于《如何快速分析Linux服务器的性能问题》以上内容仅供参考,若您的权利被侵害,请联系13825271@qq.com
本文网址:http://www.25820.com/tutorial/14_2162962.html