1.工具概览
图源:http://www.brendangregg.com/linuxperf.html
2.网络
一个网络包的旅程:https://102.alibaba.com/detail/?id=166
2.1 网络连通性
#检查网络连通性(通过ping网关/对端网关/对端进行分段测试,通过tcpdump确认是否收到包) netstat -rn #查看网关,以0.0.0.0开始的行的gateway是默认网关 ping 127.0.0.1 -s 64000 #指定packet size进行ping,一般应小于1ms sudo tcpdump -i eth2 icmp #抓ping的包 #检查网卡状态 ip addr show #state是否是UP ip link set eth0 up #启用被禁用的网卡 ip route show ifconfig route -n #查看路由表 ip route get 127.0.0.1 //返回目标ip最终实际所选用的路由 #检查iptables配置 sudo iptables --list-rules #检查tc配置 sudo tc qdisc show dev eth2 #telent检查端口连通性 telnet 127.0.0.1 2376
2.2 网络连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
2.3 网络流量
sar -n DEV 1 #查看网卡流量,排查本地网卡是否有问题
tsar –traffic #查看网络出入流量
2.4 丢包重传
tsar --tcp #查看retran,按照经验值健康网络应该在0 ~ 0.x ip -s link #显示所有网络接口统计数据 ip -s -s link ls eth2 #显示特定网络接口统计数据 ip命令详解:https://www.jellythink.com/archives/469 tsar:https://github.com/alibaba/tsar
2.5 端口占用
#查看当前机器上进程监听的tcp端口,还会显示进程:users:(("downloader",pid=16201,fd=9)) sudo ss -pl -t -s #查找打开某端口的进程 sudo ss -lp | grep 22 sudo lsof -i :port #列出使用某个端口的进程 #列举出处于 FIN-WAIT-1状态的源端口为 80或者 443,目标网络为 193.233.7/24所有 tcp套接字 ss -o state FIN-WAIT-1 src :80 src :443 dst 192.168.25.100/24 ss命令详解:https://www.cnblogs.com/ftl1012/p/ss.html
3. 磁盘IO
一次磁盘io的旅程:https://blog.51cto.com/alanwu/1286553
3.1 空间
1.磁盘整体使用
df #空间情况 df -i #inode是否满
2.寻找最大目录
sudo du -sh --time /* sudo du -sh --time /home/* ......
3.查看磁盘是否为ssd
cat /sys/block/sda/queue/rotational #进行查看,返回值0即为SSD;返回1即为HDD lsscsi
4.有时候df看到的磁盘空间使用率,和sudo du -sh 看到的不一致。
原因一般是因为存在大量被删除的问题,但是还处于open状态。可以通过如下命令找到这些被删除但是还没某些进程open的文件:
sudo lsof -P -n | grep deleted
3.2 util
tsar --io -s util -I sda #最近一天磁盘使用率 tsar --io -s util -i 1 -l -I sdb #实时磁盘使用率
磁盘util很高时,如何找到占用IO资源最多的进程
iotop -o -P
pidstat -d
iodump
blktrace
3.2.1 iostat
iostat -m -x 1 #以MB为单位每秒刷新一次
iostat详解:https://chuansongme.com/n/1151503748524
3.2.2 blktrace
sudo blktrace -d /dev/sda6 -o - | blkparse -i - #实现块请求追踪 ### 追踪并进行分析 sudo blktrace -d /dev/sda6 #会在当前目录存储trace数据,为避免占用磁盘和IO需要提前确定好执行目录 sudo blkparse -i sda6 sudo blkparse -i sda6 -d sda6.blktrace.bin sudo btt -i sda6.blktrace.bin #可以查看不同进程的io情况 ### 对设备/dev/sda的io监控120秒,每2秒显示一次 blktrace /dev/sda -a issue -a complete -w 120 -o - | blkiomon -I 2 -h - WR:R表示是read操作,W表示write操作,B是barrier operation,S是synchronous operation
blktrace详解:
https://www.sohu.com/a/157462582_314773
http://blog.chinaunix.net/uid-24774106-id-4096470.html
3.2.3 debugfs
3.2.3.1查找blktrace中的io请求对应的文件
1.首先根据blktrace可以找到io对应的扇区
sudo blktrace -d /dev/sda6 -o - |blkparse -i - |grep A >/tmp/t # 8,0 9 1 1266874889.709080680 1495 A WS 392236696 + 8 <- (8,6) 76279448
如上:76279448就是扇区号。
2.根据扇区通过debugfs找到对应文件
查看设备block大小:
sudo tune2fs -l /dev/sda6|grep "Block size" #查看块大小 sudo debugfs -R "stats" /dev/sda6|grep "Block size" #查看块大小 sudo fdisk -l /dev/sda6 #可以查看sector size
扇区转换为block号(扇区*SectorSize/BlockSize):
$ echo 76279448*512/4096 | bc 9534931
3.block号转换为inode
$ sudo debugfs -R "icheck 9534931" /dev/sda6 debugfs 1.42.9 (28-Dec-2013) Block Inode number 9534931 8
4.inode转换为文件名
$ sudo debugfs -R "ncheck 8" /dev/sda6 debugfs 1.42.9 (28-Dec-2013) Inode Pathname
注:inode number是8,无法找到对应的文件名。这是因为8是ext3/4文件系统中的日志文件的inode,它是隐藏文件,所以无法找到。
5.使用lsof查找打开文件的进程
sudo lsof /home/test_bin
使用blktrace统计磁盘块I/O访问频率:
http://blog.chinaunix.net/uid-24774106-id-4096470.html
扇区与文件系统转换关系:
https://www.bbsmax.com/A/Vx5MYABm5N/
3.2.3.2 查找文件对应的block
debugfs -R "stat /path/to/file" /dev/<partition> hdparm --fibmap /path/to/filename Linux下的IO监控与分析:https://www.cnblogs.com/quixotic/p/3258730.html iodump:https://github.com/true/aspersa-mirror/blob/master/iodump
3.2.4 lsof(打开文件的进程|进程打开的文件)
lsof /filepath/file #查看谁在使用某个文件 lsof +D /filepath/filepath2/ #递归查看某个目录下的文件信息 lsof -c mysql #列出某个binary打开的文件信息 lsof -p 123,456,789 #显示多个进程打开的文件信息 lsof -i #列出所有网络连接 lsof -i :port #列出使用某个端口的进程 lsof -d descrip #列出文件描述符对应的文件信息 lsof -d fd1-fd2 #根据文件描述符范围列出对应文件信息
3.2.5 fdisk
sudo fdisk -l /dev/sda
3.3 ext4
查看文件系统是否4k对齐:
sudo dumpe2fs /dev/loop1 |grep "Block size"
extent:https://ext4.wiki.kernel.org/index.php/Ext4_Design
extent tree:https://www.cnblogs.com/youngerchina/p/5624478.html
debugfs:https://linux.die.net/man/8/debugfs
debugfs: stat 1.log
debugfs: ex -l 1.log
4.CPU
查看cpu信息
cat /proc/cpuinfo lscpu
top # P(根据cpu排序) M(根据内存排序) R(反向排序) H(显示线程) top -p PID #显示某个进程 top -H -p pid #显示某个进程所有活跃线程开销情况 uptime pstack PID #内核stack cat /proc/237332/task/*/stack | grep -v poll| grep -v futex | grep -v fastpath | grep -v sleep | grep -v ffff
load高,查看处于D和R状态的进程
ps -e -L h o state,pid,wchan:32,cmd | awk '{if($1=="R"||$1=="D"){print $0}}' top -p $cspid -H -b -n2 | grep " D " #看看有没有线程D住
查看所有进程的cpu使用
pidstat -u -p ALL #查看所有进程cpu使用
5.内存
5.1 内存占用
free -g cat /proc/19312/smaps #查看虚拟内存地址空间 pmap -d $PID #查看内存空间
cgroup配置
sudo lssubsys -am
5.2 内存泄漏
gperftools
5.3 内存越界
AddressSanitizer&ThreadSanitizer原理与应用
6. 进程
6.1 进程状态异常
1.pstack
2.strace(系统调用/进程异常退出/共享内存/性能)
sudo strace -tt -T -p PID #查看进程系统调用及耗费时间 #查看进程运行中访问的文件 strace -tt -e trace=file -f ./test_exit #trace=process|file|network|signal|desc|ipc strace详解:https://www.linuxidc.com/Linux/2018-01/150654.htm
6.2 进程资源占用
6.2.1 pidstat
pidstat -u -p ALL #查看所有进程cpu使用 pidstat -r #查看所有进程内存使用 pidstat -d #查看所有进程IO使用 pidstat -w #查看所有进程上下文切换情况
6.2.2 ps
ps -C command_name #某个command对应的所有进程 ps --ppid 766 #显示进程776的所有子进程 ps u -p 776 -L #显示进程776的所有线程 ps -e --forest #进程树形结构 ps -f --forest -C sshd #打印某个进程的树形结构 ps -eo pid,ppid,fgroup,ni,lstart,etime #打印父进程、进程启动时间等 ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem|head #根据内存占用排序 ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu|head #根据cpu排序 ps -eo euser,ruser,suser,fuser,f,comm,label #用户信息 watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head' #查看ps实时执行结果
6.2.3 top
top # P(根据cpu排序) M(根据内存排序) R(反向排序) H(显示线程)
6.3 父子进程管理
父进程退出确保子进程也退出
python:http://evans.io/legacy/posts/killing-child-processes-on-parent-exit-prctl/
c:https://www.cnblogs.com/beixiaobei/p/9064815.html
7.性能profiling
perf :http://www.brendangregg.com/perf.html
gperftools:https://github.com/gperftools/gperftools
8.系统日志
8.1 dmesg
dmesg -T #显示友好时间 sudo vim /var/log/messages /var/clone/cloneinfo
dmesg相对时间手动转换方法(xxx代表dmesg中的相对时间戳):
MY_TIME=xxx date -d "1970-01-01 UTC `echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+$MY_TIME"|bc ` seconds" +'%Y-%m-%d %H:%M:%S'
dmesg | grep -i memory #内存相关 dmesg | grep -i dma #磁盘相关 dmesg | grep -i usb #usb dmesg | grep -i tty #串口相关 dmesg --facility=daemon --level=err,warn #指定要打印的日志类型和日志级别,详情查看dmesg -h dmesg -L #带颜色显示 dmesg |grep -E "net|eth|bond|link" #网络相关 dmesg |grep -i "cpu" #网络相关
8.2 其他系统日志
/var/log/kern
var/log目录日志详解:https://www.plesk.com/blog/featured/linux-logs-explained/
9.辅助工具
9.1 awk
1.统计log文件里面的各个操作的个数,并按照多少排序
awk ‘{++opMap[$1]} END {for(key in opMap) print key,”\t”,opMap[key]}’|sort -n -k 2
2.计算key/value最大value值
awk ‘{if($2>opMap[$1]){opMap[$1]=$2}} END {for(key in opMap) print key,”\t”,opMap[key]}’|sort -n -k 2
3.条件表达式
awk -F “::” ‘$5 >= 3 && $6 >=3 {print $0}’
awk的条件表达式:(https://likegeeks.com/awk-command/)
9.2 代码查看工具
codeviz egypt ncc
9.3 gdb
9.3.1 基本使用
http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html
watch var #变量值变化时会停住
set follow-fork-mode child #在fork子进程时,gdb跟踪进子进程
x/nfu #help x查看具体用法 list *addr #查看addr处指令对应的代码片段 info symbol 0x400a46 #查看某地址对应的符号表信息 info line *0x400a46 #查看某地址对应的代码行,类似addr2line
9.3.2 非交互式获取所有线程bt
gdb -q --batch --ex "set height 0" -ex "thread apply all bt full" [可执行文件] [core文件]
除了通过-ex直接指定要运行的命令,还可以通过 -x gdb_cmd_file指定命令文件。
此外还可以在交互式模式下,设置logging,将输出结果存到文件中
set logging file output.filename set logging on xxx #gdb命令 set logging off
9.3.3 查看stl容器对象
http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt
下载上述文件,打开gdb在里面执行:source dbinit_stl_views-1.03.txt
之后即可使用pmap pset等命令查看map set的内容。
9.3.4 汇编
汇编基础:
深入浅出GNU X86-64 汇编:https://blog.csdn.net/pro_technician/article/details/78173777
C/C++中手动获取调用堆栈:https://blog.csdn.net/qq_44906504/article/details/89246475
9.4 coredump
https://averageradical.github.io/Linux_Core_Dumps.pdf
9.4.1 core文件产生
ulimit -c -f #查看core文件大小限制 sysctl kernel.core_pattern #查看core文件保存路径 gcore $PID #产生core文件 readelf -a core.14391 #查看core文件信息
9.4.2 core文件分析
(gdb) thread apply all bt #查看所有线程堆栈 (gdb) dump binary memory dump.bin 0x00007f3498000000 0x00007f34a0000000 #dump内存数据到文件 (gdb) maint print msymbols var.syms #print符号表内容到文件var.syms
https://sourceware.org/gdb/onlinedocs/gdb/Searching-Memory.html
(gdb) find [/sn] start_addr, +len, val1 [, val2, …] (gdb) find [/sn] start_addr, end_addr, val1 [, val2, …]
core_analyzer:http://core-analyzer.sourceforge.net/index.html
9.5 编译链接
gcc -E search.c #宏展开 ldd c++filt addr2line nm
编译链接加载:https://blog.csdn.net/farmwang/article/details/72934821
9.6 shell快捷键
9.7 shell常用命令
1.日志备份 mkdir log_bakup ln *LOG* log_bakup/ #注意后面记得清理不使用的备份日志 2.文件操作 split #将一个文件分割成多个 join # find ./ -name "xxx*" | xargs cat > outpt.txt #合并多个文件到一个