对于程序员来说,整个计算机系统由四个重要的模块组成,分别是:CPU,网路,c盘,显存。在我们的程序或则系统出现问题时,我们应当分别有一定先后次序的对这四块进行排查。而在Linux系统下,有好多高效的工具,可以帮助我们剖析定位问题。本文对于Linux下常用的一些工具进行一些简单的介绍,帮助读者能对那些工具有一个初步的了解。假如有不对的地方,欢迎随时见谅交流。
1.CPU
对于cpu我们主要介绍top,strace,perf,vmstat。
1.1top
top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息检测系统性能和运行信息的实用工具。
Top常用的可选参数和其对应的涵义如下:
(1)-c:显示完整的命令;
(2)-d:屏幕刷新间隔时间;
(3)-i:设置间隔时间;
(4)-u:指定用户名;
(5)-p:指定进程;
(6)-n:循环显示的次数。
top执行上去的疗效如下:
前五行是系统整体的统计信息。第一行是任务队列信息,第二行和第三行为进程和CPU的信息,最后两行为显存信息。下边对一些比较重要的参数进行说明。
Loadaverage:0.60,0.94,1.04。loadaverage表示系统在过去1分钟5分钟15分钟的任务队列的平均厚度。这个值越大就表示系统CPU越忙碌。
Cpu(s):5.0%us(用户空间占用的cpu百分百),3.9%sy(系统空间占用的cpu比率),0.0%ni(用户进程空间内改变过优先级的用户占用的cpu比率),90.9%id(空闲cpu的比率),0.2%wa(等待输入输出cpu的比率)。
Mem:817280kbuffers(用作内核缓存的显存量)。
Swap:c盘交换区容量。
1.2strace
strace可以跟踪到一个进程形成的系统调用,包含参数、返回值、执行消耗的时间。
strace的常用的选项以及选项对应的含意如下:
(1)-c统计每一系统调用的所执行的时间,次数和出错的次数等
(2)-f跟踪由fork调用所形成的子进程
(3)-t在输出中的每一行前加上时间信息
(4)-tt在输出中的每一行前加上时间信息(微妙级)
(5)-T显示每一调用所耗的时间
(6)-etrace=set只跟踪指定的系统调用。诸如:-etrace=open,close,read,write表示只跟踪这四个系统调用。默认的为set=all
(7)-etrace=file只跟踪有关文件操作的系统调用
(8)-etrace=process只跟踪有关进程控制的系统调用
(9)-etrace=network跟踪与网路有关的所有系统调用
(10)-estrace=signal跟踪所有与系统讯号有关的系统调用
(11)-etrace=ipc跟踪所有与进程通信有关的系统调用
(12)-ofilename将strace的输出写入文件filename-ppid跟踪指定的进程pid
比如执行stracecat/dev/null,会得到如下输出:
每一行都是一条系统调用,等号右边是系统调用的函数名及其参数,右侧是该调用的返回值。假如你晓得你要找的是哪些,你可以让strace只跟踪一些类型的系统调用。诸如你须要瞧瞧在loadconfigure脚本上面执行的程序上面系统调用ececve的调用情况,则只须要输入这样一条shell命令:strace-f-oloadconfigure-strace.txt-eexecve./loadconfigure
再比如,我们晓得ActLogicSvr的进程号是16789,则可以执行strace-p16789-c来统计ActLogicSvr在某一段时间系统调用的统计情况。结果如下所示:
这儿很清楚的告诉你调用了这些系统函数,调用次数多少,消耗了多少时间等等这种信息,这个对我们剖析一个程序来说是十分有用的。
1.3Perf
perf是Linux的性能调优工具。perf工具的常用命令包括top,record,report等。
perftop命令拿来显示程序运行的整体状况。该命令主要拿来观察整个系统当前的状态,例如可以通过查看该命令的输出来查看当前系统最历时的内核函数或某个用户进程。Perfstat的运行疗效如下:
perfrecord命令则拿来记录指定风波在程序运行过程中的信息,而Perfreport命令则拿来报告基于上面record命令记录的风波信息生成的程序运行状况报告。我们一般用命令perfrecord-g-ppid将进程在命令运行期间的各项指令运行所占CPU的比列存在perf.data上面(-g表示记录函数之间的调用关系)。再用perfreport--call-graph--stdio将刚才的统计结果展示下来。
perfrecord带-g选项时,perfreport的运行疗效:
perfrecord不带-g选项时,perfreport的运行疗效:
1.4vmstat
vmstat是一个很全面的性能剖析工具,可以观察到系统的进程状态、内存使用、虚拟显存使用、磁盘的IO、中断、上下问切换、CPU使用等。
vmstat的输出如下:
procs:
-r:运行队列中进程数目,这个值也可以判别是否须要降低CPU。(常年小于1)
-b:由于io处于阻塞状态的进程数。
memory:
-swap:使用虚拟显存大小
-free:空闲化学显存大小
-buff:用作缓冲的显存大小
-cache:用作缓存的显存大小
swap:
si:每秒从交换区讲到显存的大小,由c盘调入显存
so:每秒写入交换区的显存大小,由显存调入c盘
io:
-bi:从块设备读入的数据总数(读c盘)(KB/s)
-bo:写入到块设备的数据总数(写c盘)(KB/s)
system:
-in:每秒形成的中断次数
-cs:每秒形成的上下文切换次数
cpu:
-us:用户进程消耗的CPU时间比率
-sy:内核进程消耗的CPU时间比率
-wa:IO等待消耗的CPU时间比率
-id:CPU处在空闲状态时间比率
2.网路2.1netstat命令
netstat命令拿来复印Linux中网路系统的状态信息,可让你得悉整个Linux系统的网路情况。
netstat的常用的选项如下:
(1)-a(all)显示所有选项
(2)-t(tcp)仅显示tcp相关选项
(3)-u(udp)仅显示udp相关选项
(4)-l(listen)仅列举有在Listen(窃听)的服务状态
(5)-p(program)显示构建相关链接的程序名
(6)-r(route)显示路由信息,路由表
(7)-e(extend)显示扩充信息
(8)-c每隔一个固定时间,执行该netstat命令。
在这儿我们简单备考一下TCP三次握手和四次挥手的过程,以便下边解释netstat中tcp的各类状态。
TCP三次握手的过程如下:
(1)主动联接端发送一个SYN包给被动联接端;
(2)被动联接端收到SYN包后,发送一个带ACK的SYN包给主动联接端。
(3)主动联接端发送一个带ACK标志的包给被动联接端,握手动作完成。
TCP的四次挥手过程如下:
(1)主动关掉端发送一个FIN包给被动关掉端。
(2)被动关掉端收到FIN包后,发送一个ACK包给主动关掉端。
(3)被动关掉端发送了ACK包后linux 输入法,再发送一个FIN包给主动关掉端。
(4)主动关掉端收到FIN包后,发送一个ACK包。当被动关掉端收到ACK后,四次挥手动作完成,联接断掉。
下边我们解释一下netstat中tcp联接对应的各类状态。
(1)LISTEN:侦听状态,等待远程机器的联接恳求。
(2)SYN_SEND:在TCP三次握手期间,主动联接端发送了SYN包后,步入SYN_SEND状态,等待对方的ACK包。
(3)SYN_RECV:在TCP三次握手期间,主动接收端收到SYN包后,步入SYN_RECV状态。
(4)ESTABLISHED:完成TCP三次握手后,主动联接端步入ESTABLISHED状态。此时,TCP联接早已构建,可以进行通讯。
(5)FIN_WAIT_1:在TCP四次挥手时,主动关掉端发送FIN包后,步入FIN_WAIT_1状态。
(6)FIN_WAIT_2:在TCP四次挥手时,主动关掉端收到ACK包后,步入FIN_WAIT_2状态。
(7)TIME_WAIT:在TCP四次挥手时,主动关掉端发送了ACK包然后,步入TIME_WAIT状态,等待最多2MSL时间,让被动关掉端收到ACK包。
(8)CLOSING:在TCP四次挥手期间,主动关掉端发送了FIN包后,没有收到对应的ACK包,却收到了对方的FIN包,此时步入CLOSING状态。
(9)CLOSE_WAIT:在TCP四次挥手期间,被动关掉端收到FIN包后,步入CLOSE_WAIT状态。
(10)LAST_ACK:在TCP四次挥手时,被动关掉端发送FIN包后,步入LAST_ACK状态,等待对方的ACK包。
netstat-te(显示出所有的tcp联接)执行上去的疗效如下:
netstat的常用技巧:
(1)netstat-p|grep19626:得到进程号19626的进程所打开的所有端口
(2)netstat-tpl:查看当前tcp窃听端口,须要显示窃听的程序名。
(3)netstat-c2:隔两秒执行一次netstat,持续输出
2.2lsof
lsof命令用于查看进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。在linux环境下,任何事物都以文件的方式存在,通过文件不仅仅可以访问常规数据,还可以访问网路联接和硬件。在使用TCP的UDP的时侯查看linux系统内核,系统在后台都为该应用程序分配了一个文件描述符。无论这个文件的本质怎样,该文件描述符为应用程序与基础操作系统之间的交互提供了通用插口。
lsof的使用示例如下:
输出的各项的含意如下:
COMMAND:进程的名称
PID:进程标示符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符辨识该文件。如cwd、txt等
TYPE:文件类型,如DIR、REG等
DEVICE:指定c盘的名称
SIZE:文件的大小
NODE:索引节点(文件在c盘上的标示)
NAME:打开文件的准确名称
Lsof的常用技巧:
(1)lsofabc.txt:查看所有打开了文件abc.txt的进程。
(2)lsof-ppid:显示进程打开的所有的文件。
2.3tcpdump
tcpdump可以将网路中传送的数据包完全查获出来提供剖析。它支持针对网路层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑句子来帮助你去除无用的信息。
tcpdump的常用参数:
(1)-nn,直接以IP及PortNumber显示,而非主机名与服务名称。
(2)-i,前面接要「监听」的网路插口,比如eth0,lo,ppp0等等的插口。
(3)-w,假如你要将窃听所得的数据包数据存储出来,用这个参数就对了。前面接文件名。
(4)-c,窃听的数据包数,假如没有这个参数,tcpdump会持续不断的窃听,直至用户输入[ctrl]-c为止。
(5)-A,数据包的内容以ASCII显示,一般拿来捉取WWW的网页数据包资料。
(6)-e,使用资料联接层(OSI第二层)的MAC数据包数据来显示。
(7)-q,仅列举较为简略的数据包信息,每一行的内容比较精简。
(8)-X,可以列举十六补码(hex)以及ASCII的数据包内容,对于窃听数据包内容很有用。
(9)-r,从前面接的文件将数据包数据读下来。那种「文件」是早已存在的文件,但是这个「文件」是由-w所制做出来的。
tcpdump的常见用法:
(1)tcpdump-ieth1host***.***.***.***:抓取所有经过eth1,目的或源地址是***.***.***.***的网路数据。
(2)tcpdump-ieth1dsthost***.***.***.***:抓取所有经过eth1,目的地址是***.***.***.***的网路数据。
(3)tcpdump-ieth1srchost***.***.***.***:抓取所有经过eth1,源地址是***.***.***.***的网路数据。
(4)tcpdump-ieth1port36000:抓取所有经过eth1,目的端口或源端口是36000的网路数据。
(5)tcpdump-ieth1srcport36000:抓取所有经过eth1,源端口是36000的网路数据。
(6)tcpdump-ieth1dstport36000:抓取所有经过eth1,目的端口是36000的网路数据。
(7)tcpdump-ieth1'srchost***.***.***.***&&srcport36000':抓取所有经过eth1,目的地址是10.136.12.1且目的端口是36000的网路数据。
(8)在10.136.12.1机器上我们通过top晓得了ActLogicSvr的进程id为16789。之后通过netstat-ap|grep16789得到ActLogicSvr窃听的端口是10014。如右图所示:
之后我们通过tcpdump-ieth1'port10014'-xxx抓取通过10014端口的所有的包。我们通过模拟插口测试的方式给ActLogicSvr发一条恳求。抓到的包结果如下:
从抓到的包上我们可以清楚的看见tcp联接构建的三次握手到数据传输到tcp联接断掉四次挥手的过程(前三个数据包是三次握手的过程,最后四个数据包是四次挥手的过程,中间的为数据传输所形成的网路数据包)。
3显存3.1valgrind
valgrind是在Linux程序中广泛使用的调试应用程序。它尤其擅长发觉显存管理的问题,可以检测程序运行时的显存泄露问题等。我们在使用valgrind时也主要用到它的显存泄露检查功能,即memcheck功能。它检测所有对显存的读/写操作,并截取所有的malloc/new/free/delete调用。因而memcheck工具才能侦测到以下问题:
(1)使用未初始化的显存
(2)读/写早已被释放的显存
(3)读/写显存越界
(4)读/写不恰当的显存栈空间
(5)显存泄露
(6)使用malloc/new/new[]和free/delete/delete[]不匹配。
(7)src和dst的重叠valgrind的可选的参数以及对应的含意如下所示:
(1)-version显示valgrind内核的版本,每位工具都有各自的版本。
(2)q–quiet安静地运行,只复印错误信。
(3)v–verbose更详尽的信息,降低错误数统计。
(4)-trace-children=no|yes跟踪子线程
(5)-track-fds=no|yes跟踪打开的文件描述
(6)-time-stamp=no|yes降低时间戳到LOG信息
(7)-log-fd=输出LOG到描述符文
(8)-log-file=将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
(9)-log-file-exactly=输出LOG信息到file
(10)-log-file-qualifier=取得环境变量的值来做为输出信息的文件名。
(11)-log-socket=ipaddr:port输出LOG到socket,ipaddr:port
LOG信息输出:
(1)-xml=yes将信息以xml格式输出,只有memcheck可用
(2)-num-callers=showcallersinstacktraces[12]
(3)-error-limit=no|yes假如太多错误,则停止显示新错误?[yes]
(4)-error-exitcode=假如发觉错误则返回错误代码[0=disable]
(5)-db-attach=no|yes当出现错误linux中文乱码,valgrind会手动启动调试器gdb。[no]
(6)-db-command=启动调试器的命令行选项[gdb-nw%f%p]适用于Memcheck工具的相关选项:
(1)--leak-check=no|summary|full要求对leak给出详尽信息?[summary]
(2)--leak-resolution=low|med|highhowmuchbtmerginginleakcheck[low]
(3)--show-reachable=no|yesshowreachableblocksinleakcheck?[no]
示例:valgrind--leak-check=full/usr/local/app/taf/tafnode/data/TenFortune.WeChatProxySvr/bin/WeChatProxySvr--config=/usr/local/app/taf/tafnode/data/TenFortune.WeChatProxySvr/conf/TenFortune.WeChatProxySvr.config.conf-trace-child=yes。执行的结果:
4c盘4.1iotop
iotop命令是一个拿来监视c盘I/O使用状况的top类工具。iotop具有与top相像的UI,其中包括PID、用户、I/O、进程等相关信息。Linux下的IO统计工具如iostat,nmon等大多数是只能统计到per设备的读写情况,若果你想晓得每位进程是怎样使用IO的就比较麻烦查看linux系统内核,使用iotop命令可以很便捷的查看。
iostat命令选项:
-o:只显示有io操作的进程
-nNUM:显示NUM次,主要用于非交互式模式。
-dSEC:间隔SEC秒显示一次。
-pPID:监控的进程pid。
-uUSER:监控的进程用户。
iotop的执行疗效: