Linux进程排查实战之strace和lsof命令使用指南

发布时间:2026/5/26 7:11:24

Linux进程排查实战之strace和lsof命令使用指南 服务起不来日志没报错。进程在跑但就是不干活。这种问题最恶心看日志看不出问题看监控也没异常。这时候就需要strace和lsof这两个神器了。strace跟踪系统调用strace能看到进程在做什么系统调用相当于给进程装了个监控摄像头。基本用法12345678# 跟踪一个命令stracels# 跟踪正在运行的进程strace-p pid# 跟踪子进程strace-f -p pid案例一服务启动卡住现象Java服务启动后卡住不打印任何日志。123456# 找到进程号psaux |grepjava# 假设是12345# strace跟踪strace-p 12345输出futex(0x7f8a8c000000, FUTEX_WAIT_PRIVATE, 0, NULL卡在futex说明在等锁。进一步看是什么锁1strace-p 12345 -e tracefutex -T结合jstack看线程栈12jstack 12345 thread.dumpgrep-A 20BLOCKEDthread.dump发现是启动时连接数据库数据库连不上超时时间设太长了。案例二文件读写问题现象服务很慢但CPU和内存都不高。12345# 只看文件相关的调用strace-p 12345 -e tracefile# 或者看所有IOstrace-p 12345 -e traceread,write,open,close输出open(/data/logs/app.log, O_WRONLY|O_APPEND) 3write(3, 2024-12-23 10:00:00 INFO..., 1024) 1024close(3) 0open(/data/logs/app.log, O_WRONLY|O_APPEND) 3write(3, 2024-12-23 10:00:00 INFO..., 1024) 1024close(3) 0...每次写日志都open-write-close频繁的文件操作导致性能差。改成保持文件句柄打开或者用异步日志。案例三网络问题现象服务偶尔超时。12# 只看网络相关strace-p 12345 -e tracenetwork -T输出connect(5, {sa_familyAF_INET, sin_porthtons(3306), sin_addrinet_addr(10.0.0.1)}, 16) -1 ETIMEDOUT (Connection timed out) 30.001234连接数据库超时30秒问题找到了。常用参数1234567891011121314151617# -f跟踪子进程strace-f -p 12345# -T显示每个调用耗时strace-T -p 12345# -t显示时间戳strace-t -p 12345# -c统计系统调用次数和耗时strace-c -p 12345# -o输出到文件strace-o trace.log -p 12345# 组合使用strace-f -T -t -o trace.log -p 12345统计分析1strace-c -p 12345输出% time seconds usecs/call calls errors syscall------ ----------- ----------- --------- --------- ----------------45.23 2.345678 234 10000 write30.12 1.234567 1234 1000 read20.11 0.987654 98 10000 futex4.54 0.234567 23 10000 clock_gettime------ ----------- ----------- --------- --------- ----------------100.00 4.802466 31000 total一眼就能看出时间花在哪了。lsof列出打开的文件Linux里一切皆文件lsof能看到进程打开了什么文件、网络连接、设备等。基本用法1234567891011# 查看进程打开的所有文件lsof-p pid# 查看某个文件被谁打开lsof/var/log/app.log# 查看某个端口lsof-i :8080# 查看某个用户的所有打开文件lsof-u root案例一端口被占用12# 谁占用了8080端口lsof-i :8080输出COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 12345 root 123u IPv6 123456 0t0 TCP *:8080 (LISTEN)进程12345占用了8080端口。案例二文件句柄泄漏现象服务运行一段时间后报Too many open files。12345# 查看进程打开的文件数lsof-p 12345 |wc-l# 按文件类型分组统计lsof-p 12345 |awk{print $5}|sort|uniq-c |sort-rn输出5000 IPv43000 REG1000 DIR5000个网络连接明显有连接泄漏。12# 看看都连了谁lsof-p 12345 -i |head-20输出COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 12345 root 123u IPv4 123456 0t0 TCP 10.0.0.1:54321-10.0.0.2:3306 (ESTABLISHED)java 12345 root 124u IPv4 123457 0t0 TCP 10.0.0.1:54322-10.0.0.2:3306 (ESTABLISHED)java 12345 root 125u IPv4 123458 0t0 TCP 10.0.0.1:54323-10.0.0.2:3306 (ESTABLISHED)...全是连数据库的连接池用完没归还。案例三删除的文件还在占用空间12# 查看已删除但仍被引用的文件lsofL1输出COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAMEjava 12345 root 10w REG 253,1 10737418240 0 12345 /var/log/app.log (deleted)日志文件被删了但进程还引用着10G空间释放不掉。解决重启服务或者truncate文件1234# 找到文件描述符路径ls-l/proc/12345/fd/10# 清空内容但不关闭句柄: /proc/12345/fd/10案例四网络连接分析1234567891011121314# 查看所有网络连接lsof-i# 只看TCPlsof-i tcp# 只看某个状态lsof-i |grepESTABLISHED# 统计连接数lsof-i |grepESTABLISHED |wc-l# 按目标地址分组lsof-i |grepESTABLISHED |awk{print $9}|cut-d-f2 |cut-d:-f1 |sort|uniq-c |sort-rn组合使用排查思路先用top/htop看整体用ps看进程状态用lsof看打开了什么用strace看在做什么

相关新闻