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

 更新时间:2025年12月23日 15:17:49   作者:嘻哈baby  
这篇文章主要为大家详细介绍了Linux进程排查实战之strace和lsof命令使用的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

服务起不来,日志没报错。进程在跑,但就是不干活。

这种问题最恶心,看日志看不出问题,看监控也没异常。

这时候就需要strace和lsof这两个神器了。

strace:跟踪系统调用

strace能看到进程在做什么系统调用,相当于给进程装了个监控摄像头。

基本用法

# 跟踪一个命令
strace ls

# 跟踪正在运行的进程
strace -p <pid>

# 跟踪子进程
strace -f -p <pid>

案例一:服务启动卡住

现象:Java服务启动后卡住,不打印任何日志。

# 找到进程号
ps aux | grep java
# 假设是12345

# strace跟踪
strace -p 12345

输出:

futex(0x7f8a8c000000, FUTEX_WAIT_PRIVATE, 0, NULL

卡在futex,说明在等锁。

进一步看是什么锁:

strace -p 12345 -e trace=futex -T

结合jstack看线程栈:

jstack 12345 > thread.dump
grep -A 20 "BLOCKED" thread.dump

发现是启动时连接数据库,数据库连不上,超时时间设太长了。

案例二:文件读写问题

现象:服务很慢,但CPU和内存都不高。

# 只看文件相关的调用
strace -p 12345 -e trace=file

# 或者看所有IO
strace -p 12345 -e trace=read,write,open,close

输出:

open("/data/logs/app.log", O_WRONLY|O_APPEND) = 3
write(3, "2024-12-23 10:00:00 INFO...", 1024) = 1024
close(3) = 0
open("/data/logs/app.log", O_WRONLY|O_APPEND) = 3
write(3, "2024-12-23 10:00:00 INFO...", 1024) = 1024
close(3) = 0
...

每次写日志都open-write-close,频繁的文件操作导致性能差。

改成保持文件句柄打开,或者用异步日志。

案例三:网络问题

现象:服务偶尔超时。

# 只看网络相关
strace -p 12345 -e trace=network -T

输出:

connect(5, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("10.0.0.1")}, 16) = -1 ETIMEDOUT (Connection timed out) <30.001234>

连接数据库超时30秒,问题找到了。

常用参数

# -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

统计分析

strace -c -p 12345

输出:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 45.23    2.345678         234     10000           write
 30.12    1.234567        1234      1000           read
 20.11    0.987654          98     10000           futex
  4.54    0.234567          23     10000           clock_gettime
------ ----------- ----------- --------- --------- ----------------
100.00    4.802466                 31000           total

一眼就能看出时间花在哪了。

lsof:列出打开的文件

Linux里一切皆文件,lsof能看到进程打开了什么文件、网络连接、设备等。

基本用法

# 查看进程打开的所有文件
lsof -p <pid>

# 查看某个文件被谁打开
lsof /var/log/app.log

# 查看某个端口
lsof -i :8080

# 查看某个用户的所有打开文件
lsof -u root

案例一:端口被占用

# 谁占用了8080端口
lsof -i :8080

输出:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    12345 root  123u  IPv6 123456      0t0  TCP *:8080 (LISTEN)

进程12345占用了8080端口。

案例二:文件句柄泄漏

现象:服务运行一段时间后报"Too many open files"。

# 查看进程打开的文件数
lsof -p 12345 | wc -l

# 按文件类型分组统计
lsof -p 12345 | awk '{print $5}' | sort | uniq -c | sort -rn

输出:

5000 IPv4
   3000 REG
   1000 DIR

5000个网络连接?明显有连接泄漏。

# 看看都连了谁
lsof -p 12345 -i | head -20

输出:

 COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    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)
...

全是连数据库的,连接池用完没归还。

案例三:删除的文件还在占用空间

# 查看已删除但仍被引用的文件
lsof +L1

输出:

COMMAND   PID USER   FD   TYPE DEVICE    SIZE/OFF NLINK  NODE NAME
java    12345 root   10w   REG  253,1 10737418240     0 12345 /var/log/app.log (deleted)

日志文件被删了,但进程还引用着,10G空间释放不掉。

解决:重启服务,或者truncate文件:

# 找到文件描述符路径
ls -l /proc/12345/fd/10
# 清空内容但不关闭句柄
: > /proc/12345/fd/10

案例四:网络连接分析

# 查看所有网络连接
lsof -i

# 只看TCP
lsof -i tcp

# 只看某个状态
lsof -i | grep ESTABLISHED

# 统计连接数
lsof -i | grep ESTABLISHED | wc -l

# 按目标地址分组
lsof -i | grep ESTABLISHED | awk '{print $9}' | cut -d'>' -f2 | cut -d':' -f1 | sort | uniq -c | sort -rn

组合使用

排查思路

  • 先用top/htop看整体
  • 用ps看进程状态
  • 用lsof看打开了什么
  • 用strace看在做什么

实战:服务假死排查

现象:服务进程在,但不响应请求。

# 1. 看进程状态
ps aux | grep java
# 状态是Sl,正常

# 2. 看打开的文件和连接
lsof -p 12345 | wc -l
# 8000+,有点多

# 3. 看网络连接
lsof -p 12345 -i | grep -c ESTABLISHED
# 5000+,太多了

# 4. 看连接状态分布
ss -tnp | grep 12345 | awk '{print $4}' | sort | uniq -c
# 大量CLOSE_WAIT

# 5. strace看在做什么
strace -p 12345 -e trace=network
# 卡在accept上,但新连接进不来

根因:连接池满了,CLOSE_WAIT状态的连接没有正确关闭。

实战:CPU 100%排查

# 1. top找到占用CPU的进程
top -c
# PID 12345 CPU 99%

# 2. 看线程CPU使用
top -H -p 12345
# TID 12346 CPU 99%

# 3. 把线程ID转成16进制
printf "%x\n" 12346
# 303a

# 4. jstack看线程栈(Java)
jstack 12345 | grep -A 30 "0x303a"

# 5. 或者用strace看系统调用
strace -p 12346 -c

远程排查

有时候问题机器在远程,需要登录排查。

我们有几台服务器在不同机房,之前用跳板机一层层跳很麻烦。现在用星空组网把所有机器组到一起,直接SSH过去就能用strace、lsof排查,效率高多了。

常用命令速查

# strace速查
strace -p <pid>                    # 跟踪进程
strace -f -p <pid>                 # 跟踪包括子进程
strace -e trace=network -p <pid>   # 只看网络
strace -e trace=file -p <pid>      # 只看文件
strace -c -p <pid>                 # 统计
strace -T -p <pid>                 # 显示耗时

# lsof速查
lsof -p <pid>                      # 进程打开的文件
lsof -i :<port>                    # 谁占用端口
lsof -i tcp                        # 所有TCP连接
lsof +L1                           # 已删除但仍占用的文件
lsof -u <user>                     # 用户打开的文件

总结

工具用途典型场景
strace跟踪系统调用卡死、慢、报错看不出原因
lsof看打开的文件/连接端口占用、文件泄漏、连接泄漏

排查原则:

  • 从宏观到微观
  • 从现象到根因
  • 不确定就多看几遍

这两个工具用熟了,大部分疑难杂症都能查出来。

以上就是Linux进程排查实战之strace和lsof命令使用指南的详细内容,更多关于Linux strace和lsof命令的资料请关注脚本之家其它相关文章!

相关文章

  • 给Apache下的网站加速的方法总结

    给Apache下的网站加速的方法总结

    这篇文章主要介绍了给Apache下的网站加速的方法,很有实用价值,需要的朋友可以参考下
    2014-07-07
  • linux服务器中开放端口实现过程

    linux服务器中开放端口实现过程

    本文介绍了如何在Linux上使用firewall命令开放端口,包括查看状态、开启和关闭端口、添加和移除IP段规则、批量添加区间端口、开放系统服务等操作
    2025-11-11
  • 虚拟机安装Linux rhel7.3操作系统(具体步骤)

    虚拟机安装Linux rhel7.3操作系统(具体步骤)

    这篇文章主要介绍了虚拟机安装Linux rhel7.3操作系统(具体步骤),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Linux脚本(shell)的使用方式

    Linux脚本(shell)的使用方式

    这篇文章主要介绍了Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • CentOS 7 在vmware中的网络设置详细介绍

    CentOS 7 在vmware中的网络设置详细介绍

    这篇文章主要介绍了CentOS 7 在vmware中的网络设置详细介绍的相关资料,这里对主要网络问题进行了一一介绍及如何解决,需要的朋友可以参考下
    2016-11-11
  • linux中各种锁机制的使用与区别详解

    linux中各种锁机制的使用与区别详解

    这篇文章主要给大家介绍了关于linux中各种锁机制的使用与区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • CentOS8.1搭建Gitlab服务器详细教程

    CentOS8.1搭建Gitlab服务器详细教程

    这篇文章主要介绍了CentOS8.1搭建Gitlab服务器详细教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Linux系统非正常关机导致磁盘异常的问题及解决

    Linux系统非正常关机导致磁盘异常的问题及解决

    文章介绍了在VMware ESXi虚拟化环境中,由于断电导致的Linux系统非正常关机和磁盘异常问题及其解决方案,主要问题包括文件系统损坏和报错信息,解决方案涉及检查和修复`/etc/fstab`文件中的语法错误,并使用`dmsetup`命令恢复设备映射
    2025-11-11
  • apache的access.log和error.log减肥

    apache的access.log和error.log减肥

    我的服务器是用apache搭建的,里面的access.log和error.log这两个文件要经常上去看,和清理,如果时间忙,忘记看和清理了,过不了多久,这两个文件就膨胀的非常的大,打都打不开了。
    2009-09-09
  • linux配置定时任务全过程

    linux配置定时任务全过程

    文章介绍了crontab命令在Linux系统中的使用方法和配置信息,包括定时任务的概念、查看服务、格式和语法,以及实例
    2026-03-03

最新评论