Linux有诸多优秀的工具帮助我们分析服务器各项性能指标和协助开发调试工作。下面只列举比较基础的命令,且一般是集成在linux环境中而不需再次安装的命令。更多更详细的命令可以参考 https://github.com/brendangregg/perf-tools
A、CPU进程相关 常用工具列举下:uptime、ps、top、mpstat、pidstat等
uptime: 查看系统运行时间,平均负载等。
ps:可查看某个进程占用CPU资源百分比;查看线程信息 ps -eLf
top/htop/atop:显示的信息同ps接近,但是top可以了解到CPU消耗,可以根据用户指定的时间来更新显示;
top -Hp pid(主线程id) 可以看到多线程程序中所有线程的状态。
mpstat: 可以查看所有CPU的平均信息,还能查看指定CPU的信息;
pidstat: 对于显示某个进程的状态,耗费时间等非常有用。
可通过以下命令查看缺页中断信息
ps -o majflt,minflt -C <program_name>
ps -o majflt,minflt -p <pid>
其中, majflt 代表 major fault ,指大错误, minflt 代表 minor fault ,指小错误。这两个数值表示一个进程自启动以来所发生的缺页中断的次数。其中 majflt 与 minflt 的不同是, majflt 表示需要读写磁盘,可能是内存对应页面在磁盘中需要 load 到物理内存中,也可能是此时物理内存不足,需要淘汰部分物理页面至磁盘中。
例如,下面是 mysqld 的一个例子。
mysql@ TLOG_590_591:~> ps -o majflt,minflt -C mysqld
MAJFLT MINFLT
144856 15296294
如果进程的内核态 CPU 使用过多,其中一个原因就可能是单位时间的缺页中断次数多个,可通过以上命令来查看。
如果 MAJFLT 过大,很可能是内存不足。
如果 MINFLT 过大,很可能是频繁分配 / 释放大块内存 (128k) , malloc 使用 mmap 来分配。对于这种情况,可通过 mallopt(M_MMAP_THRESHOLD, <SIZE>) 增大临界值,或程序实现内存池。
ps -o majflt,minflt -C <program_name>
ps -o majflt,minflt -p <pid>
其中, majflt 代表 major fault ,指大错误, minflt 代表 minor fault ,指小错误。这两个数值表示一个进程自启动以来所发生的缺页中断的次数。其中 majflt 与 minflt 的不同是, majflt 表示需要读写磁盘,可能是内存对应页面在磁盘中需要 load 到物理内存中,也可能是此时物理内存不足,需要淘汰部分物理页面至磁盘中。
例如,下面是 mysqld 的一个例子。
mysql@ TLOG_590_591:~> ps -o majflt,minflt -C mysqld
MAJFLT MINFLT
144856 15296294
如果进程的内核态 CPU 使用过多,其中一个原因就可能是单位时间的缺页中断次数多个,可通过以上命令来查看。
如果 MAJFLT 过大,很可能是内存不足。
如果 MINFLT 过大,很可能是频繁分配 / 释放大块内存 (128k) , malloc 使用 mmap 来分配。对于这种情况,可通过 mallopt(M_MMAP_THRESHOLD, <SIZE>) 增大临界值,或程序实现内存池。
B、内存相关 常用工具:free、vmstat
free:可查看内存的总数、已使用、空闲内存数,swap使用(当系统没有足够物理内存来应付所有请求的时候就会用到swap设备,swap设备可以是一个文件,也可以是一个磁盘分区。不过要小心的是,使用swap的代价非常大。如果系统没有物理内存可用,就会频繁swapping,如果swap设备和程序正要访问的数据在同一个文件系统上,那会碰到严重的IO问题,最终导致整个系统迟缓,甚至崩溃)情况等,特别提醒,如果swap使用较多,说明服务器内存不怎么够用了;
Linux系统内存中的cache(free 输出中的cached)并不是在所有情况下都能被释放当做空闲空间用的,即使可以释放cache,也并不是对系统来说没有成本的。总结一下要点,我们应该记得这样几点:
1).当cache作为文件缓存被释放的时候会引发IO变高,这是cache加快文件访问速度所要付出的成本。
2).tmpfs中存储的文件会占用cache空间,除非文件删除否则这个cache不会被自动释放。
3).使用shmget方式申请的共享内存会占用cache空间,除非共享内存被ipcrm或者使用shmctl去IPC_RMID,否则相关的cache空间都不会被自动释放。
4).使用mmap方法申请的MAP_SHARED标志的内存会占用cache空间,除非进程将这段内存munmap,否则相关的cache空间都不会被自动释放。
5).实际上shmget、mmap的共享内存,在内核层都是通过tmpfs实现的,tmpfs实现的存储用的都是cache。
2).tmpfs中存储的文件会占用cache空间,除非文件删除否则这个cache不会被自动释放。
3).使用shmget方式申请的共享内存会占用cache空间,除非共享内存被ipcrm或者使用shmctl去IPC_RMID,否则相关的cache空间都不会被自动释放。
4).使用mmap方法申请的MAP_SHARED标志的内存会占用cache空间,除非进程将这段内存munmap,否则相关的cache空间都不会被自动释放。
5).实际上shmget、mmap的共享内存,在内核层都是通过tmpfs实现的,tmpfs实现的存储用的都是cache。
vmstat:可监控虚拟内存使用情况、空闲内存、缓冲、cache等指标,和free工具类似。服务器是否发生swap 可以通过 vmstat 1 查看。
C、磁盘I/O相关 常用工具:iostat、fio、swapon
iostat:可获取每秒读写的数据块数、所有读写块数等,可对磁盘读写性能有个大体了解,并可以模拟顺序以及随机读写磁盘操作;
fio:另一款强大的io压力测试工具,这个工具最大的特点是使用简单,支持的文件操作非常多, 可以覆盖到我们能见到的文件使用方式。
swapon: 显示swap设备的使用情况,如果你启动了swap设备的话。
badblocks 检测磁盘是否故障 --> time dd if=/dev/zero of=/test.dbf count=100000 bs=10k oflag=direct 检测IO 速度 -->
iostat -x -d -k 1 查看IO读写性能, %util 是否过高 --> iotop -o 找出机器上io较高的进程 --> 对cgi频繁IO写操作的目录/usr/local/stat/log/挂载到tmpfs格式的磁盘下,mount -t tmpfs -o size=20m tmpfs /tmpfs; mount -o bind /tmpfs/ /usr/local/stat/log/ 看io 是否能降下来(注:tmpfs格式的磁盘,就是将数据IO操作都在内存进行,可以大大提高IO速度,对某些操作频繁且属于小文件的IO操作很有加速效果)--> strace -p 跟踪io高的进程,看执行什么操作,或者有什么错误产生。
一个实例:cgi需要通过logagent上报数据,上报的前提是需要读取logagent的配置文件:/usr/local/stat/bin/msglog.conf。但是,由于这个这批机器没有安装logagent,所以导致了读取配置文件失败。读取配置文件失败之后,cgi频繁对文件/usr/local/stat/log/logapi_syserr.bin 以trunc方式刷新覆盖写入。虽然是直接的trunc刷新,但是由于磁盘扇区一般是512。同时,linux page cache的大小是4KB,在non-direct IO 的情况下,IO都是先写到linux的page cache里。所以io操作一般情况最少要修改512字节(一般是修改4KB)。再乘以cgi进程每秒的读写次数(次/秒),所以即使只写4个字节,io上看起来几十上百k是正常的。
D、网络I/O相关 常用工具:netstat、tcpdump、route、iptarf、netperf、nicstat、ping/traceroute
netstat:是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息;
tcpdump:用于监视TCP/IP连接并直接读取数据链路层的数据包头。可以指定哪些数据包被监视、哪些控制要显示格式;
-w xx.pcap 写入到文件,可以使用 wireshark 打开再用 wireshark 语法过滤下。收包发包都在本机的话记得 -i lo
route:可以为ifconfig命令配置的网卡设置静态路由,在本地 IP 路由表中显示和修改条目网络命令;
iptarf:可用于查看本机网络的吞吐量,获得网络传输速率;
netperf:可以模拟服务器和客户端网络收发,测试网络吞吐量大小;
iperf:类似于netperf,模拟服务器和客户端网络收发,测试最大TCP和UDP带宽性能,能够提供网络吞吐率信息, 以及震动、丢包率、最大段和最大传输单元大小等统计。
nicstat: 监控网络接口的状态如吞吐量等,类似iostat的输出格式。
ping/traceroute:比较常见,查看网络是否畅通。
网络带宽使用情况可以自行通过/proc/net/dev文件进行统计。
E、开发测试相关 常用工具:readelf、hexdump/xxd、od、objdump、nm、telnet/nc
readelf:以可读方式展示elf文件格式,包括(目标文件/可执行文件/共享库)
hexdump/xxd:将文件内容以16进制打印
od:可选进制打印文件内容
objdump:将机器指令反汇编
nm:列出目标文件的symbols
strings:即打印文件中的可打印字符串(print the strings of printable characters in files),常用来在二进制文件中查找字符串,与grep配合使用
telnet/nc :测试网络连接客户端
wget/curl:模拟http请求客户端,支持代理、cookie等。
wget 如果将link用引号括起来,如 wget 'http://baidu.com' -O tmp.down 则url 不能是 https:\/\/ptop.only.wip.la:443\/http\/baidu.com
curl 正常需要把 [] {} 等用 \ 转义,否则会出现 [globbing] illegal character in range specification at pos xx 的错误,也可以设置参数
-g/--globoff
This option switches off the "URL globbing parser". When you set this option, you can
specify URLs that contain the letters {}[] without having them being interpreted by curl
itself. Note that these letters are not normal legal URL contents but they should be
encoded according to the URI standard.
specify URLs that contain the letters {}[] without having them being interpreted by curl
itself. Note that these letters are not normal legal URL contents but they should be
encoded according to the URI standard.
-k, --insecure Allow connections to SSL sites without certs (H)
valgrind/AddressSanitizer:内存泄露检测,会降低程序性能,asan 比 valg 表现要好。
F、跟踪调试相关 常用工具:strace、ltrace、dtrace/ftrace、blktrace
strace: 跟踪运行进程的系统调用耗费时间、出错信息、参数传递等。
strace -tt -T -p pid(可以是线程的pid)
pstack:其实是 gstack 的软连接,而gstack本身是基于gdb封装的shell脚本,重点是输入thread apply all bt 这个交互命令.
该命令要求输出所有的线程堆栈信息.对GDB输出的结果, 通过管道并借助sed命令进行了替换和过滤。
ltrace:跟踪运行进程的函数库调用耗费时间、出错信息、参数传递等。
dtrace/ftrace:上述两个工具的综合。dtrace is a tracing tool whichruns at the system level - this means you can trace all processes, into and out of the kernel, rather than selecting a single process to trace.
blktrace:Block I/O event tracer
pt-pmp :is a poor man’s profiler, inspired by http://poormansprofiler.org. It can create and summarize full stack traces of processes on Linux. Summaries of stack traces can be an invaluable tool for diagnosing what a process is waiting for.
pstack {pid of mysqld} > pid.info pt-pmp pid.info
F、性能评测相关常用工具:perf top、perf record、gprof
perf record:可以用来了解程序各函数的实时运行情况。它采用定期采样的方式,统计各函数出现的比例。排名较高的函数,要么是耗时长被多次统计到,要么是频繁调用被多次统计到,无论哪种情况,这些函数都是消耗系统资源的魔头,是优化的好对象。
perf top:主要用于实时分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数、
模块函数与内核函数,甚至能够定位到热点指令。默认的性能事件为cpu cycles。perl top -p pid(可以是线程的pid)
模块函数与内核函数,甚至能够定位到热点指令。默认的性能事件为cpu cycles。perl top -p pid(可以是线程的pid)
gprof:可以用来统计程序各函数的真实耗时情况,通过它可以精确地了解到各函数的耗时,这样哪些函数需要优化,也就不言而喻了。
H、大而全的综合工具:sar/collectl、dstat、查看/proc/pid/xxx 各种信息(如 /proc/pid/fd 查看本进程打开的文件描述符,
lsof -p pid)、sysctl、/sys 各种信息
CPU不行的表现有两种:1)CPU被耗精光;2)CPU富余idle,但程序过载了。第一种,CPU都被吃光了,计算资源都没了,程序性能也就不可能更进一步了。第二种,也是常见的一种,CPU没被吃光,但程序却过载了,这种情况主要是因为程序被挂起在等待某些事件,造成等待的原因有两种:1)同步阻塞,2)内存发生swap(内存不行了)。
下面的这个例子 sar -u(如下图),就属于第二种情况:CPU idle富余,但程序过载了。由图可知,idle富余的同时,基本无iowait,这说明程序自我阻塞不在IO方面(也从侧面证明了不是swap引起的阻塞),那么引起阻塞的最大嫌疑就是互斥锁了。
下面的这个例子 sar -u(如下图),就属于第二种情况:CPU idle富余,但程序过载了。由图可知,idle富余的同时,基本无iowait,这说明程序自我阻塞不在IO方面(也从侧面证明了不是swap引起的阻塞),那么引起阻塞的最大嫌疑就是互斥锁了。
参考:
https://github.com/brendangregg/perf-tools
http://crtags.blogspot.com/2012/04/dtrace-ftrace-ltrace-strace-so-many-to.html
https://danielmiessler.com/study/tcpdump/
http://ufsdump.org/papers/oscon2009-linux-monitoring.pdf