我的服务器运行Ubuntu 12.04 LTS(精确),我有一个奇怪的问题。 服务器托pipe一个用于数据收集的大型网站。 该网站是在PHP中,并使用Zend框架。 数据在MySQL数据库中。 部分数据(来自调查)每小时(cron作业)被渲染成Excel文件(使用PHPExcel库)。 这个过程(一个PHP / Zend框架脚本)是为每个客户端完成的,每个客户端都有一个不同的数据集,有时会花费很多时间(30分钟以上)。
一旦达到30分钟,进程的状态就会从R变为D.奇怪的是,D状态的进程通常是“不可驱动的”,但是这个进程可以像任何其他进程一样被杀死。 以下是正常运行过程中的示例输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www 16089 0.5 0.8 311640 31708 ? S 09:34 0:39 /usr/sbin/apache2 -k start www 17635 0.6 0.6 305020 23396 ? S 10:52 0:18 /usr/sbin/apache2 -k start www 18520 0.0 0.0 63104 1960 pts/0 S 11:32 0:00 su www www 18521 0.0 0.1 23236 4516 pts/0 S 11:32 0:00 bash www 18621 98.8 68.1 2665208 2416568 pts/0 R 11:33 10:48 php run.php -a hourly www 18659 0.6 0.6 302848 22948 ? S 11:34 0:03 /usr/sbin/apache2 -k start www 18876 0.0 0.0 18160 1244 pts/0 R+ 11:44 0:00 ps ux
你可以看到这个过程是资源密集型的:它已经被修剪了很多,它仍在进行手术,但是我需要它来完成,所以我可以得到最终的Excel文件。 这个过程logging了大量的活动(每个Excel文件约300k个日志),并且日志文件总是突然结束。 没有任何我能find的错误logging。
下面是30分钟后的相同进程列表:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www 18034 1.0 0.7 312412 26632 ? S 11:13 0:33 /usr/sbin/apache2 -k start www 18245 2.1 0.4 303656 16912 ? S 11:25 0:49 /usr/sbin/apache2 -k start www 18520 0.0 0.0 63104 296 pts/0 S 11:32 0:00 su www www 18521 0.0 0.0 23236 968 pts/0 S 11:32 0:00 bash www 18621 96.3 85.0 3969192 3012596 pts/0 D 11:33 30:08 php run.php -a hourly www 18659 0.4 0.5 302856 19136 ? S 11:34 0:08 /usr/sbin/apache2 -k start www 19431 0.0 0.0 18160 1240 pts/0 R+ 12:04 0:00 ps ux
如果仍然运行,进程仍然会消耗资源,但什么都不做。 没有更多logging。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www 18621 9.1 80.0 4030532 2835032 ? D 11:33 33:19 php run.php -a hourly
请注意,进程状态在正好30分钟后会发生变化,根据服务器负载情况,将会处理更多或更less的数据。 有趣的是,这只发生在生产服务器上。 我的开发服务器Ubuntu 12.04也没有这个问题。
有没有什么东西会导致进程正常运行最多30分钟,然后将状态更改为D? 什么可能导致PHP脚本最终在D状态?
首先,处于D状态的进程处于不可中断的睡眠状态(通常为IO) 。
通常是什么导致进程进入这个状态是执行阻塞系统调用 。
你可以看到最后一次使用strace
调用你的进程:
strace -fp <pid>
由于D状态通常是由IO操作引起的,因此使用lsof
来检查进程打开的文件也是有用的:
lsof -p <pid>