一台基于Linux操作系统的服务器在运行时,也会代表各种参数信息。一般来说,运维人员和系统管理员会对这些数据极为敏感,但是这些参数对于开发人员来说也是非常重要的,尤其是当你的程序运行不正常时,这些线索往往会帮助快速定位和跟踪问题。这里只是提供一些简单的工具来检查系统的相关参数。当然,很多工具也是通过对/proc和/sys下的数据进行分析处理来工作的,而那些更细致、更专业的性能监控和调优可能需要更专业的工具(perf、systemtap等)和技术才能完成。毕竟系统性能监控本身就是一个大问题。1.CPU和内存1.1top?~top第一行后面的三个值分别是系统在之前1、5、15的平均负载,也可以看出系统负载在上升,稳定,和下降。当这个值超过CPU的可执行单元数时,就意味着CPU的性能已经饱和,成为瓶颈。第二行统计了系统的任务状态信息。运行自然不用多说,包括CPU上运行的和会被调度运行的;sleeping通常是等待事件(如IO操作)完成的任务,细分可以包括可中断和不可中断类型;stopped是一些被挂起的任务,一般是在前台任务上发送SIGSTOP或操作Ctrl-Z来挂起它;zombie僵尸任务,虽然进程终止资源会自动回收,但是包含退出任务的任务描述符需要被父进程访问后才能被释放。显示为defunct状态,不管是因为父进程提前退出还是没有被wait调用,如果出现这样的进程,要特别注意是不是程序设计有误。第三行的CPU使用率根据类型有以下几种情况:√(us)user:CPU处于nice值低(高优先级)用户态的时间(nice<=0)。一般情况下,只要服务器不是很空闲,大部分的CPU时间应该都用在这里来执行这样的程序陷入内核态来执行特定的服务;通常这个值会比较小,但是当服务器进行密集IO时,这个值会比较大√(ni)nice:CPU处于高nice值(lowpriority)用户态以低优先级运行所花费的时间(好>0)。默认情况下,这里不会统计新启动的进程nice=0,除非通过renice或者setpriority()手动修改了程序的nice值√(id)idle:CPU处于空闲状态(执行kernelidlehandler)占用时间√(wa)iowait:等待IO完成的时间√(hi)irq:系统处理硬件中断消耗的时间√(si)softirq:系统处理软中断消耗的时间,记住软中断分为softirqs,tasklets(其实是前者的特例),workqueues,这里不知道算什么时间,毕竟workqueues的执行已经不是中断上下文了√(st)steal:It只有在虚拟机的情况下才有意义,因为虚拟机下的CPU也是共享物理CPU的,所以这段时间表示虚拟机等待hypervisor调度CPU的时间,这也意味着hypervisor将CPU调度到其他CPU以用于ex这段时间执行,这段时间的CPU资源被“偷走”了。这个值在我的KVMVPS机器上不是0,而是大约0.1。可以用来判断VPS是否超售吗?很多时候CPU占用率高是有一定意义的,这也为服务器CPU占用率高指出了相应的排查思路:√当用户占用率过高时,通常是某些个别进程占用较多这个时候通过top就很容易找到程序了;这时,如果怀疑程序异常,可以使用perf等思路寻找热调用函数做进一步排查;√当系统占用率过高时,如果IO操作(包括终端IO)比较大,可能会导致这部分CPU占用率高,比如在文件服务器,数据库服务器等类型的服务器上,否则(例如>20%)很可能是内核和驱动模块的某些部分有问题;√当nice入住率过高时,通常是有意为之的行为。当进程的发起者知道某些进程占用高CPU时,它会设置它的nice值,以保证它不会压倒其他进程的CPU使用请求;√当iowait占用率过高时,通常表示某些程序的IO操作效率很低,或者IO对应设备的性能太低导致读写操作需要很长时间才能完成;√当irq/softirq占用率过高时,很有可能是某些外设出现问题,导致大量的irq请求。这时候查看/proc/interrupts文件,找出问题所在;√盗用率过高时,无良厂商虚拟机超卖!第四行和第五行是物理内存和虚拟内存(swap分区)的信息:total=free+used+buff/cache,现在buffers和cachedMem的信息加在一起了,但是buffers和cachedMem的关系是很多地方不同没说清楚。其实通过数据对比,这两个值就是/proc/meminfo中的Buffers和Cached字段:Buffers是原始磁盘的块缓存,主要缓存文件系统的元数据(比如superblock信息等).)在原始块的形式下,这个值一般比较小(20M左右);Cached用于读取和缓存特定文件,以提高文件访问效率。可以说是用于文件系统中的文件缓存。而availMem是一个新的参数值,用来表示在不swapping的情况下,可以给新打开的程序多少内存空间,大致相当于free+buff/cached,这也印证了上面的说法,free+buffers+cachedMem是真正可用的物理内存。而且,使用swap分区不一定是坏事,所以swap分区的使用率不是一个很重要的参数,但是频繁的swapin/out也不是什么好事。这种情况需要注意,通常表示物理内存不足。最后是每个程序的资源使用列表,其中CPU使用是所有CPU内核使用的总和。通常在执行top的时候,程序本身会读取大量的/proc操作,所以基本上top程序本身都会名列前茅。top虽然功能很强大,但通常用于在控制台实时监控系统信息。不适用于系统负载信息的长期(天、月)监控。同时,它会错过短暂的进程,无法给出统计信息。1.2vmstatvmstat是top之外的另一个常用的系统检测工具。下面截图是我用-j4编译boost的系统负载。r表示可运行进程数,数据大致一致;b表示不可中断的休眠进程数;swpd表示使用的虚拟内存量,与top-Swap-used的值意义相同,而且如手册中所说,通常情况下,buffer数量远小于cachedMem,buffers一般在20M量级;io域中的bi和bo表示每秒接收和发送到磁盘的块数(blocks/s);系统域中的in表示每秒块时钟系统中断(包括时钟中断)的次数,cs表示进程切换引起的上下文切换次数。说到这里,想必很多人纠结编译linux内核时,-j参数应该是CPUCore还是CPUCore+1?通过修改上面-j参数的值编译boost和linux内核,同时启动vmstat监控。发现两种情况下上下文切换基本没有变化,只有在-j值明显增加后上下文切换才会明显增加。看来没必要我太纠结这个参数了,虽然我没有测试具体的编译时间。根据资料,如果不是在系统启动或者benchmark的状态下,参数contextswitch>100000的程序肯定有问题。1.3pidstat如果你想全面而具体地跟踪一个进程,没有什么比pidstat更合适——你可以将堆栈空间、页面错误、主动和被动切换等信息尽收眼底。这个命令最有用的参数是-t,它可以列出进程中每个线程的详细信息。-r:显示页面错误和内存使用情况。页面错误是程序需要访问的页面映射在虚拟内存空间但尚未加载到物理内存。pagefault的两种主要类型是√minflt/s指的是minorfaults,当需要访问的物理页面由于某种原因(如共享页面、缓存机制等)已经存在于物理内存中,但是有在当前进程的页表中没有引用,MMU只需要设置相应的表项即可,这个开销相当小√majflt/s指的是重大故障,MMU需要在当前申请一个空闲的物理页availablephysicalmemory(如果没有freepage可用,需要将其他物理page切换到Swapspace来释放freephysicalpages),然后从外部加载数据到物理page中,并设置相应的entry,这个cost是相当高,和前面的-s有几个数据层面的区别:栈使用状态,包括StkSize为线程保留的栈空间,以及StkRef实际使用的栈空间。使用ulimit-s发现CentOS6.x默认栈空间大小为10240K,而CentOS7.x和Ubuntu系列默认栈空间大小为8196K,也细分为cswch/s等因素导致的主动切换如等待资源,统计nvcswch/s线程CPU时间造成的被动切换。所以这个杀手级特性-C可以指定某个字符串,如果Command中包含该字符串,就会打印并统计程序的信息,-l可以显示完整的程序名和参数?~pidstat-w-t-C"ilaw"-l从这点来看,如果单看单线程,尤其是多线程任务,pidstat比常用的ps要好!1.4其他当需要单独监控单个CPU的情况时,除了htop之外,还可以使用mpstat查看SMP处理器上各个Core的工作负载是否均衡,是否有一些热点线程占用了Core。?~mpstat-PALL1如果想直接监控某个进程占用的资源,既可以使用top-utaozj过滤掉其他不相关的用户进程,也可以使用下面的方法进行选择。ps命令可以自定义打印入口信息:while:;执行ps-eo用户、pid、ni、pri、pcpu、psr、comm|grep'alawd';睡觉1;done如果想理清继承关系,可以使用以下常用参数来展示Process树状结构,展示效果比pstree详细漂亮多了?~psaxjf2.DiskIOclassiotop可以直观的展示真实的-每个进程和线程的时间磁盘读取速度;lsof不仅可以显示普通文件(用户)的打开信息,还可以操作/dev/sda1等设备文件的打开信息,所以比如当分区无法卸载时,可以使用lsof查看磁盘分区的使用状态,加上+fg参数可以额外显示文件打开标志。2.1iostat?~iostat-xz1其实不管你用iostat-xz1还是sar-d1,磁盘的重要参数是:√avgqu-s:发送I/O请求的平均等待队列长度到设备,对于单个磁盘如果值>1表示设备饱和,除多个磁盘阵列的逻辑磁盘服务时间的总和;√svctm:发送到设备的I/O请求的平均服务时间(ms),如果svctm非常接近await,说明几乎没有I/O等待,磁盘性能很好,否则磁盘队列等待时间较长,磁盘响应较差;√%util:设备的利用率,表示每秒I/O工作时间的比例,当%util>60%时单个磁盘的性能会下降(体现在await会增加),当它关闭时到100%,设备饱和,具有多个磁盘阵列的逻辑磁盘除外;另外,虽然被监控的磁盘性能比较差,但并不一定影响应用程序的响应,内核通常使用I/O异步技术,并使用读写缓存技术来提高性能,但这受限于上述物理内存限制。上述参数对于网络文件系统也很有用。3、网络性能对服务器的重要性不言而喻。iptraf这个工具可以直观的显示网卡的收发速度信息,比较简单方便。通过sar-nDEV1也可以得到类似的吞吐量信息,网卡标配了最大速率信息,比如100M网卡、千兆网卡,方便查看设备利用率.通常,网络开发中最关心的不是网卡的传输速率,而是针对特定UDP和TCP连接的丢包率、重传率、网络延迟等。3.1netstat?~netstat-s显示系统启动以来各个协议的整体数据信息。虽然参数信息比较丰富有用,但是累计值只能从当前系统的网络状态信息中获取,除非运行两次,或者通过手表眼可以看到数值变化趋势。所以通常使用netstat检测端口和连接信息:netstat–all(a)–numeric(n)–tcp(t)–udp(u)–timers(o)–listening(l)–program(p)–timers可以取消域名反向查询,加快显示速度;比较常用的是?~netstat-antp#列出所有TCP连接?~netstat-nltp#列出所有本地TCP监听套接字,不要加-a参数3.2Sarsar是一个非常强大的工具。它可以管理各种CPU、磁盘和页面交换。这里使用-n主要是用来分析网络活动。我们只关心TCP和UDP这几个协议的数据信息。下面的命令除了显示正常情况下的报文段和数据报的发送和接收外,还包括TCP?~sudosar-nTCP,ETCP1√active/s:本地发起的TCP连接,比如通过connect(),TCP状态从CLOSED->SYN-SENT√passive/s:远程发起的TCP连接,比如通过accept(),TCP状态从LISTEN->SYN-RCVD√retrans/s(tcpRetransSegs):每秒TCP重传次数,通常在网络质量差或服务器过载后丢包的情况下,会根据TCP确认重传机制进行重传操作√isegerr/s(tcpInErrs):每秒接收错误数据包(如校验失败)UDP?~sudosar-nUDP1√noport/s(udpNoPorts):每秒收到的数据报数,但指定目的端口上没有应用程序√idgmerr/s(udpInErrors):除了以上原因收到的数据报数由机器发送但无法发送。当然,这些数据一定程度上可以说明网络的可靠性,但只有结合具体的业务需求场景才有意义。3.3tcpdumptcpdump不得不说是个好东西。大家都知道在本地调试的时候喜欢用wireshark,但是线上服务器出问题了怎么办?附录中的参考给出了思路:恢复环境,使用tcpdump抓包,当问题再次出现时(比如日志显示或者某个状态),就可以结束抓包了,tcpdump本身有-C/的-W参数可以限制抓包存储文件的大小。当达到这个限制时,保存的包裹数据会自动轮换,所以整体抓包数量还是可控的。之后把数据包下线,用wireshark随便查看,岂不妙哉!tcpdump虽然没有GUI界面,但是抓包的功能一点都不弱。可以指定网卡、主机、端口、协议等各种过滤参数。捕获的数据包完整,有时间戳,在线程序的数据包分析也很容易。可以这么简单。下面是一个小测试。可以看到,Chrome在启动的时候,自动发起建立了三个与Webserver的连接。由于这里限制了dst端口参数,所以过滤掉服务器的响应包,用wireshark打开。SYNC、ACK建立连接的过程还是很明显的!使用tcpdump时,需要尽可能配置捕获过滤条件。一方面方便接下来的分析,另一方面开启tcpdump后会影响网卡和系统的性能,进而影响在线服务的性能。
