PHP 僵尸进程过多

PHP 僵尸进程过多

我今天重启了 apache 守护进程来重新加载配置文件,但之后我开始在系统上看到许多 php 僵尸进程。数量从 10 到 30 不等,它们在死机时都会占用一小部分 CPU。我应该从哪里开始调试这个问题?

我所做的修改是将每个子级的最大请求数从 0(大量内存泄漏)减少到 1000。我认为 php 进程来自从“哑”设备接收数据的脚本,即它们发送带有 GET 参数的请求而不关心结果。

一些数据:

uname -a

# uname -a
Linux <hostname> 2.6.32-71.29.1.el6.x86_64 #1 SMP Mon Jun 27 19:49:27 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

ps -aux | php 命令

# ps aux | grep php
user1     5709  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5717  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5721  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5722  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5723  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5724  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5725  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5729  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5731  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5737  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5760  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5778  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5793  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5798  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5800  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5833  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5850  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5870  3.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5875  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5876  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5877  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5886  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5926  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5939  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5941  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5961  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5962  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5973  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5977  0.0  0.2 106836  8680 ?        R    12:15   0:00 /usr/bin/php /home/user1/public_html/<script>.php
root      5981  0.0  0.0 103228   836 pts/0    S+   12:15   0:00 grep php

自由的

# free -m
             total       used       free     shared    buffers     cached
Mem:          3831       3173        658          0        183       2502
-/+ buffers/cache:        487       3344
Swap:         4031          7       4024

正常运行时间

# uptime
 12:18:10 up 105 days, 23:21,  1 user,  load average: 0.23, 0.20, 0.18

还需要什么来帮助我调试这个吗?

答案1

这不是问题。僵尸进程不会占用 CPU、内存或进程表槽以外的任何东西。您说过,僵尸进程不会停留很长时间,所以 Apache 主进程所做的只是等待子进程退出,所以有时需要一段时间才能收割终止的子进程。

答案2

僵尸进程只是一个其父进程已经死亡/被杀死,并且还没有被清理的进程。

如果在服务重启期间发生这种情况,则完全正常。您应该阅读有关 Linux 进程状态的信息,大致信息如下:

  1. 运行:这是进程正在运行或准备运行的状态。
  2. 可中断:此状态是进程的阻塞状态,等待来自另一个进程的事件或信号
  3. 不可中断:也是阻塞状态。进程因某种原因被迫停止,例如等待硬件状态或无法处理信号。
  4. 已停止:一旦进程完成,就会出现此状态。此进程可以重新启动
  5. 僵尸:在此状态下,进程将被终止,但是信息仍然保留在进程表中。

然而,如果在您正常使用 Web 服务器时发生了这种情况(毕竟,我们谈论的是 php 进程),您可能会每分钟使用 cronjob 执行一次 apache 平稳重启(service apache2 reload)来暂时修复这个问题,但这并不能解决蚕食您的可用插槽的根本问题。

在第二种情况下,您需要辨别哪个托管导致了僵尸,并且必须修复应用程序。99%的此类僵尸都是由编程不良的网站引起的。

答案3

请在使用 pcntl_fork() 分叉进程后添加代码 pcntl_wait()

$pid = pcntl_wait($status, WNOHANG);
int pcntl_wait ( int &$status [, int $options ] )

wait函数暂停当前进程的执行,直到子进程退出,或直到发出信号,其作用是终止当前进程或调用信号处理函数。如果在调用时子进程已经退出(即所谓的“僵尸”进程),则该函数立即返回。子进程使用的所有系统资源都将被释放

相关内容