掌握一些性能优化的工具和方法,需要在工作中不断积累;计算机基础知识很重要,比如网络知识、操作系统知识等,只有掌握了基础知识,才能抓住优化过程中性能问题的关键,在性能优化中也游刃有余过程。虽然监控工具可以帮助我们解决大多数问题,但有时我们需要登录到一个实例并运行一些标准的Linux性能工具。查看Netflix性能工程团队的这篇博文:https://netflixtechblog.com/linux-performance-analysis-in-60-000-milliseconds-accc10403c55,看看他们用十个命令在一分钟内诊断机器性能问题。在60秒内,您可以通过运行以下十个命令来深入了解系统资源使用情况和正在运行的进程。寻找错误和饱和度指标,因为它们都易于解释,然后是资源利用率。饱和是指资源加载超出其处理能力并且可以作为请求队列长度或等待时间公开的情况。当我们找到Linux操作系统所有关键的一级计数器时,我们会得到这样一张图:这些命令的输出有助于快速定位性能瓶颈。主要查看图中红色标记的计数器,所有资源(CPU、内存、磁盘IO等)的利用率(utilization)、饱和度(saturation)和误差(error)的度量,也就是作者提出的USE方法布伦丹·格雷格。USE方法:https://www.brendangregg.com/usemethod.htmluptimedmesg|tailvmstat1mpstat-PALL1pidstat1iostat-xz1free-msar-nDEV1sar-nTCP,ETCP1top下面我们一一介绍这些命令,更多关于这些命令的参数和说明,请参考命令的手册。1、uptime命令可以快速查看机器的负载:$uptime23:51:26up21:31,1user,loadaverage:30.02,26.43,19.02在linux系统中,平均负载是指单位时间内,系统处于runningstateand处于不可中断状态的平均进程数,即平均活跃进程数。可运行进程是指正在使用CPU或等待CPU的进程,也就是我们经常用ps命令看到的处于R状态(Running或Runnable)的进程。处于不可中断状态的进程是在内核态中处于关键进程的进程,这些进程是不可中断的。这些数据可以让我们从宏观上了解系统资源的使用情况。命令的输出分别表示1分钟、5分钟和15分钟的平均负载。通过这三个数据,可以了解服务器负载是趋于紧张还是区域正在缓和。如果1分钟平均负载高,但15分钟平均负载低,说明服务器负载高,需要进一步排查CPU资源消耗在什么地方。相反,如果15分钟平均负载高而1分钟平均负载低,则可能是CPU压力期已经过去。从上面例子的输出可以看出最近1分钟的平均负载很高,比最近15分钟的负载高很多。因此,我们需要继续调查当前系统中哪些进程消耗了大量资源。可以使用下面介绍的vmstat、mpstat等命令进一步排查。2.dmesg|尾巴$dmesg|尾部[1880957.563150]perlinvokedoom-killer:gfp_mask=0x280da,order=0,oom_score_adj=0[...][...][...][1880957.563400],anon-rss:1953348kB,file-rss:0kB[2320864.954447]TCP:PossibleSYNfloodingonport7001.Droppingrequest.CheckSNMPcounters。这将检查最后10条系统消息(如果有)。查找可能导致性能问题的错误。上面的示例包括oom-killer和TCP丢弃请求。不要错过这一步!dmesg总是值得检查。这些日志可以帮助解决性能问题。3.vmstat$vmstat1procs---------memory-------------swap-------io-----system--------cpu-----rbswpdfreebuffcachesisobiboincsussyidwast3400200889792737085918280005610961300320020088992073708591860000592132844282981100320020089011273708591860000095012154991000320020088956873712591856000481190024599900003200200890208737125918600000158984840981100^C每行会输出一些系统核心指标,这些指标可以让我们更详细的了解系统状态。Thefollowingparameter1indicatesthatthestatisticalinformationisoutputoncepersecond.Theheaderofthetableindicatesthemeaningofeachcolumn.Herearesomecolumnsrelatedtoperformancetuning:r:thenumberofprocesseswaitingforCPUresources.ThisdatacanbetterreflecttheCPUloadthantheaverageload,andthedatadoesnotincludeprocesseswaitingforIO.IfthisvalueisgreaterthanthenumberofmachineCPUcores,thenthemachine'sCPUresourcesaresaturated.free:Theamountofmemoryavailabletothesystem(inkilobytes).Iftheremainingmemoryisinsufficient,itwillalsocausesystemperformanceproblems.Thefreecommandintroducedbelowcanprovideamoredetailedunderstandingoftheusageofsystemmemory.si,so:Thenumberofswapwritesandreads.Ifthisdataisnot0,itmeansthatthesystemisalreadyusingtheswaparea(swap),andthephysicalmemoryofthemachineisinsufficient.us,sy,id,wa,st:TheserepresenttheconsumptionofCPUtime,whichrespectivelyrepresentusertime(user),system(kernel)time(sys),idletime(idle),IOwaitingtime(wait)andStolentime(stolen,generallyconsumedbyothervirtualmachines).TheseCPUtimesabovecangiveusaquickideaof??whethertheCPUisbusyornot.Generally,ifthesumofusertimeandsystemtimeisverylarge,theCPUisbusyexecutinginstructions.IftheIOwaittimeishigh,thenthebottleneckofthesystemmaybediskIO.Fromtheoutputoftheexamplecommand,itcanbeseenthatalargeamountofCPUtimeisconsumedintheusermode,thatis,theuserapplicationprogramconsumesCPUtime.这不一定是性能问题。需要和r队列一起分析。4.mpstat-PALL1$mpstat-PALL1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)07:38:49PMCPU%usr%nice%sys%iowait%irq%soft%steal%guest%gnice%idle07:38:50PMall98.470.000.750.000.000.000.000.000.000.7807:38:50PM096.040.002.970.000.000.000.000.000.000.9907:38:50PM197.000.001.000.000.000.000.000.000.002.0007:38:50PM298.000.001.000.000.000.000.000.000.001.0007:38:50PM396.970.000.000.000.000.000.000.000.003.03[…]这个命令可以显示每个CPU的使用情况。那么它可能是由单线程应用程序引起的。5.pidstat1$pidstat1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)07:41:02PMUIDPID%usr%system%guest%CPPUCPUCommand07:41:03PM090.000.940.000.941rcuos/007:41:03PM042145.665.660.0011.3215mesos-slave07:41:03PM043540.940.940.001.898java07:41:03PM065211596.231.890.001598.1127java07:41:03PM065641571.707.550.001579.2528java07:41:03PM60004601540.944.720.005.669pidstat07:41:03PMUIDPID%usr%system%guest%CPUCPUCommand07:41:04PM042146.002.000.008.0015mesos-slave07:41:04PM065211590.001.000.001591.0027java07:41:04PM065641573.0010.000.001583.0028java07:41:04PM10867181.000.000.001.000snmp-pass07:41:04PM60004601541.004.000.005.009pidstat^Cpidstat命令输出进程的CPU使用率。该命令会持续输出,不会覆盖之前的数据,方便观察系统动态。从上面的输出可以看出,两个JAVA进程占用了近1600%的CPU时间,消耗了大约16个CPU核的计算资源。6.iostat-xz1$iostat-xz1avg-cpu:%user%nice%system%iowait%steal%idle0.130.000.100.010.0099.76设备:rrqm/swrqm/sr/sw/srkB/swkB/savgrq-szavgqu-szawaitr_awaitw_awaitsvctm%UTILVDA0.000.620.030.890.577.9718.520.000.681.960.960.640.640.600.06vdb0.000.000.000.000.380.052.64414.120.000.000.840.840.840.840.840.840.540.000.000.000.000.000.000.000.000.000.000.000.000.00s.000.000.000.000.000.000.000.000.000.000.bh.;%nice%system%iowait%steal%idle0.250.000.000.000.0099.75Device:rrqm/swrqm/sr/sw/srkB/swkB/savgrq-szavgqu-szawaitr_awaitw_awaitsvctm%utilvda0.000.000.001.000.004.008.000.000.000.000.001.000.10avg-cpu:%user%nice%system%iowait%steal%idle0.000.000.000.000.00100.00iostat命令主要用来查看机器的磁盘IO状态。该命令输出的列的主要含义为:r/s,w/s,rkB/s,wkB/s:分别表示每秒读写次数和每秒读写数据量(千字节)).过多的读写可能会导致性能问题。await:IO操作的平均等待时间,单位毫秒。这是应用程序在与磁盘交互时需要消耗的时间,包括IO等待和实际操作所花费的时间。如果这个值太大,可能是硬件设备遇到了瓶颈或者出现了故障。avgqu-sz:对设备发出的平均请求数。如果该值大于1,则可能是硬件设备饱和(部分前端硬件设备支持并行写入)。%util:设备利用率。该值表示设备的繁忙程度。经验值是,如果超过60,可能会影响IO性能(可以参考IO操作的平均等待时间)。如果达到100%,说明硬件设备已经饱和。如果显示逻辑设备的数据,设备利用率并不代表后端实际硬件设备已经饱和。值得注意的是,即使IO性能不理想,也并不一定意味着应用会出现性能问题。可以使用预读和写缓存等策略来提高应用程序性能。7、free–m$free-mtotalusedfreesharedbufferscachedMem:245998245452214538359541-/+buffers/cache:23944222053Swap:000free命令可以查看系统内存的使用情况,-m参数表示以兆为单位显示。最后两列分别表示用于IO缓存的内存量和用于文件系统页面缓存的内存量。需要注意的是第二行-/+buffers/cache,好像是cache占用了很多内存空间。这是Linux系统的内存使用策略。尽可能使用内存。如果应用程序需要内存,这部分内存会立即被回收并分配给应用程序。因此,这部分内存一般也被认为是可用内存。如果可用内存很低,系统可能会使用swap区(如果配置的话),这会增加IO开销(可以在iostat命令中体现),降低系统性能。8.sar-nDEV1$sar-nDEV1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)12:16:48AMIFACEErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil12:16:49AMeth018763.005032.0020686.42478.300.000.000.000.0012:16:49AMlo14.0014.001.361.360.000.000.000.0012:16:49AMdocker00.000.000.000.000.000.000.000.0012:16:49AMIFACErxpck/stxpck/srxkB/stxkb/srxcmp/stxcmp/srxmcst/s%ifutil12:16:50AMETH019763.005101.0021999.10482.560.000.000.000.000.000.000.000.000.0012:16:16:16:50AMLO20.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00012erser命令在这里可以查看网络设备的吞吐率。在排查性能问题时,可以通过网络设备的吞吐量来判断网络设备是否饱和。如示例输出所示,eth0网卡设备的吞吐量约为22Mbytes/s,即176Mbits/sec,未达到1Gbit/sec的硬件上限。9.sar-nTCP,ETCP1$sar-nTCP,ETCP1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)12:17:19AMactive/spassive/siseg/soseg/s12:17:20AM1.000.0010233.0018846.0012:17:19AMatmptf/sestres/sretrans/sisegerr/sorsts/s12:17:20AM0.000.000.000.000.0012:17:20AMactive/spassive/siseg/soseg/s12:17:21AM17:020AM17:020/sestres/sretrans/sisegerr/sorsts/s12:17:21AM0.000.000.000.000.00^这里使用csar命令查看TCP连接状态,包括:active/s:本地每秒发起的TCP连接数,即是,由connect调用创建的TCP连接;passive/s:每秒远程发起的TCP连接数,即accept调用创建的TCP连接;retrans/s:每秒TCP重传次数;可以通过TCP连接数来判断性能问题是否是因为建立的连接过多,可以进一步判断连接是主动发起的还是被动接受的。TCP重传可能是因为网络环境不好或者服务器压力过大,导致丢包。重传会严重影响tcp的效率。您可以使用由BrendanGregg开发的轻量级tcp重传抓取器:tcpretrans。10.top$toptop-00:15:40up21:56,1user,loadaverage:31.09,29.87,29.92Tasks:871total,1running,868sleeping,0stopped,2zombie%Cpu(s):96.8us,0.4sy,0.0ni,2.7id,0.1wa,0.0hi,0.0si,0.0stKiBMem:25190241+total,24921688used,22698073+free,60448buffersKiBSwap:0total,0used,0free.554208cachedMemPIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND20248root2000.227t0.012t18748S30905.229812:58java4213root20027225446464044232S23.50.0233:35.37mesos-slave66128titancl+2002434423321172R1.00.00:00.07top5235root20038.227g54700449996S0.70.22:02.74java4299root20020.015g2.682g16836S0.31.133:14.42java1root2003362029201496S0.00.00:03.82init2root200000S0.00.00:00.02kthreadd3root200000S0.00.00:05.35ksoftirqd/05root0-20000S0.00.00:00.00kworker/0:0H6root200000S0.00.00:06.94kworker/u256:08root200000S0.00.02:38.05rcu_schedtop该命令包含了前面几个命令的检查内容。比如系统负载(uptime)、系统内存使用(free)、系统CPU使用(vmstat)等。因此,通过这个命令,可以比较全面的查看系统负载的来源。同时top命令支持排序,可以按不同的列进行排序,方便找出内存占用最多的进程、CPU占用最高的进程等进程。但是,与之前的一些命令相比,top命令的输出是一个瞬时值。如果你不一直盯着它看,你可能会错过一些线索。这时候可能需要暂停top命令的刷新来记录和对比数据。11.总结有很多工具可以解决Linux服务器的性能问题。上面介绍的一些命令可以帮助我们快速定位问题。例如,在前面的样例输出中,有多个证据证明一个JAVA进程占用了大量的CPU资源,后续可以对该应用进行性能调优。
