聊聊Linux性能优化那些事三 (系统中出现大量不可中断或者僵尸进程怎么办)
进程状态
其中对应的进程状态:
不可中断状态其实就是为了保证进程数据与迎接状态一致,并且正常情况下,不可中断状态在很短时间内就会结束。所以短时的不可中断状态进程我们一般可以忽略。但是如果系统或者硬件发送了故障,进程可能会在不可中断状态保持很久,甚至导致系统中出现大量不可中断进程。这个时候就要注意下,是不是I/O等性能问题
僵尸进程,这是多进程应用很容易碰到的问题,正常情况下,当一个进程创建了子进程后,它应该通过系统调用wait()或者waitpid()等待子进程结束,回收子进程资源,而子进程在结束后,会向它的父进程发送SIGCHLD信号,所以父进程还可以注册SIGCHLD信号的处理函数,异步回收资源
但是父进程没有这么做,或者是子进程执行太快,父进程还没来及处理子进程状态,子进程就已经提前退出了,这时候子进程就会变僵尸进程。通常僵尸进程持续时间比较短,父进程回收它的资源后会消亡、或者父进程退出后由init进程回收后也会消亡。但是一旦父进程没有处理,那么子进程一直处于僵尸进程,大量的僵尸进程会用尽PID进程号,导致新进程不能创建。
案例分析
当分析top命令输出发现两个问题:iowait太高因为
这里有两个进程出现d状态,它们可能等待I/O但是不能确定是它们导致的iowait。
iowait分析:使用dstat,它的好处可以同时查看CPU和I/O两个资源使用情况
1>在中断运行pidstat 命令
然后发现app进程在进行磁盘读,并且每秒读的数据有32MB,不过app进程到底执行啥I/O操作呢?
进程用户态和内核态区别:进程要想访问磁盘必须使用系统调用,接下来重点找出app进程的系统调用
strace正是最常用的跟踪进程系统调用的工具
结果发现没有权限,一般遇到这样情况,检查进程状态是否正常,比如继续运行ps命令,找出:
所以发现该进程已经变成Z,僵尸进程。僵尸进程都是已经退出的进程所以无法继续分析它的系统调用。但是目前top、pidstat、这类工具已经给不了太多信息。这时候,我们求助于那些基于事件记录的动态追踪工具,perf top
接着找到我们关注的进程,然后得到调用关系图
发现通过系统调用sys_read()读取数据。进程正在对磁盘进程之间读,也就是绕过了系统缓存,每个读请求都从磁盘之间读,这就是iowait升高了
僵尸进程
先找到父进程,然后在父进程里解决
发现是app应用,然后查看app应用代码,看看子进程结束处理是否正确。
最后再top一下发现问题全部解决了