2015-08-21 70 views
1

我有一个网站,定期获取大量的睡眠php进程。我的托管服务设置了20个并发运行进程的限制。如果超过限制,我的网站就会出现503错误。需要一种方法来选择性地杀死睡眠php进程

这很少见,似乎与访问我的网站的人数没有任何关联。

作为一个安全措施,我希望有一个PHP脚本的cron作业,可以杀死已经睡了10分钟以上的php进程。

我有一个PHP函数,将杀死睡眠超过10分钟的所有熟睡的MySql进程;

public function kill_sleeping_mysql_processes() 
    { 
    $result = $this->db->query("SHOW FULL PROCESSLIST"); 
    foreach($result->result_array() as $row) 
    { 
     if ($row['Command'] == "Sleep" && $row['Time'] > 600) 
     { 
      $this->db->query("KILL {$row['Id']}") 
     } 
    } 
    } 

问题是我怎么能做到这一点与PHP进程相同?

我可以用这段代码读出php进程。

exec("ps aux | less", $output); 

我可以用这段代码杀死特定的php进程,如果我有pid;

$pid = 11054; 
exec("kill -9 $pid"); 

但是我该如何选择性地杀死已经睡眠超过10分钟的php进程呢?

+0

只是好奇,如果你已经检查你的日志,并试图解决根本问题? – ficuscr

+0

是的,我试图解决根本问题无济于事......我也多次联系我的主持人的支持寻求帮助。 –

+0

它几个星期或几个月没有问题,然后突然之间我得到了一系列停滞脚本,使我的网站下降。 –

回答

0

我拼凑了一些东西在一起。虽然我在进行cron工作之前会进一步测试它,但它并不高雅,并且有点破绽,但似乎可行。

public function kill_dormant_php_processes() 
    { 
     $output_array = array(); 

     exec("ps aux | grep -v grep", $ps_output); 

     array_shift($ps_output); 

     if (count($ps_output) > 0) 
     { 
      $i = 0; 
      foreach ($ps_output as $ps) 
      { 
       $ps = preg_split('/ +/', $ps); 
       $output_array[$i]->pid = $ps[1]; 
       $output_array[$i]->stat = $ps[7]; 
       $output_array[$i]->time = $ps[9]; 
       $i++; 
      } 
     } 

     if(! empty($output_array)) 
     { 
      foreach ($output_array as $row) 
      { 
       if($row->stat == 'S' && date('H:i', strtotime($row->time)) > date('H:i', strtotime('00:01'))) 
       { 
        exec("kill -9 $row->pid"); 
       } 
      } 
     } 
    } 

我确定必须有更好的方法来做到这一点。

有人可以解释为什么00:01在读出似乎翻译为6分钟?

freedom 6933 6.0 0.1 57040 13040 ?  S 16:55 0:01 /usr/local/bin/php53.cgi -c .:/home/freedom/:/etc index.php