在后台连续运行Php脚本

在后台连续运行Php脚本,php,sockets,nohup,Php,Sockets,Nohup,我已经编写了server.php来通过tcp套接字接受来自客户端的连接。 我有用处 set_time_limit(0); include_once("include/class.db.php"); while (true) { receive_message('x.x.x.x','8855',50); } function receive_message($ipServer,$portNumber,$nbSecondsIdle) { // creating the socket... $s

我已经编写了server.php来通过tcp套接字接受来自客户端的连接。 我有用处

set_time_limit(0);
include_once("include/class.db.php");
while (true)
{
receive_message('x.x.x.x','8855',50);
}

function receive_message($ipServer,$portNumber,$nbSecondsIdle)
{
 // creating the socket...
 $socket = stream_socket_server('tcp://'.$ipServer.':'.$portNumber, $errno, $errstr);
if (!$socket)
{
echo "$errstr ($errno)<br />\n";
}
else
 {
// while there is connection, i'll receive it... if I didn't receive a message within $nbSecondsIdle seconds, the following function will stop.
while ($conn = @stream_socket_accept($socket,$nbSecondsIdle))
{
 $message= fread($conn, 1024);
 if($message!=''){
 echo 'I have received that : '.$message;
 // insert into database
 $sql = "insert into `data_log` (`id`,`message_text`) values (NULL,'$message')";
 $query=mysql_query($sql) or die(mysql_error() . "<br>" . $sql);
}
 fputs ($conn, "OK\n");
 fclose ($conn);
}
fclose($socket);
}
}
在后台运行服务器。一切都很好。但是套接字在几个小时后自动关闭,或者说php脚本在几个小时后结束。因为我需要在后台运行脚本,直到我手动停止它。 有什么问题吗?
提前感谢您

您可以在循环中运行脚本,并使用前面提到的
sleep
时间将其休眠几秒钟。例如:

while(1 < 2) {
    //your code
    sleep(1);
}

这样它就可以在后台运行,并检查它是否正在运行。使用
top
命令查看后台进程,它将以php命令的形式在顶级进程中运行。

您应该清楚地了解,php不应该用于这些事情。PHP脚本运行,做一些工作,然后死亡——这就是它的命运。在php上创建的任何恶魔都会因为某种原因而死亡

但是在php上创建恶魔非常容易。那我们该怎么办呢

对于demon脚本,您应该实现supervisor

首先,您有您的脚本,正如上面所描述的。有时,为这个脚本实现一些中断条件是很有用的,例如进程内存限制

其次,您为您的恶魔实现了监控脚本。那是什么东西?简单地说,一些脚本,您应该每1分钟从cron调用一次。此脚本将:

  • 检查您的恶魔脚本是否仍在运行。目前通过shell运行的进程可用于此目的
  • 如果你的恶魔已经终止,请运行另一个实例
  • 出口

  • 主管的概念非常有用。您可以在那里实现任何业务逻辑,例如,精确运行demon的实例数。对于RabbitMQ这样的脚本来说,这太棒了。

    好吧,您可以通过将程序输出管道化到日志文件而不是/dev/null来开始故障排除。作为一项初步措施,您可以编写一个cronjob,不时检查脚本是否仍在运行,如果仍在运行,则重新启动脚本。可能是在数据库连接关闭、脚本执行停止一段时间后,或者内存不足。请先检查您的连接。@franzgleichman使用file而不是/dev/null在一天内创建一个大约20gb的大文件。因此,我使用/dev/nulls,然后消除所有不必要的输出,这样就留下了错误消息。@Franzgleichman我已将输出通过管道传输到日志文件,现在我将在脚本终止后返回日志报告。
    while(1 < 2) {
        //your code
        sleep(1);
    }
    
    nohup php yourscript.php &