保持PHP脚本作为守护进程运行的最佳方式是什么?
保持PHP脚本作为守护程序运行的最佳方式是什么?以及检查是否需要重新启动的最佳方法是什么?保持PHP脚本作为守护进程运行的最佳方式是什么?
我有一些脚本需要全天候运行,而且大部分时间我都可以使用nohup运行它们。但是如果他们失败了,监控它的最好方法是什么,以便它可以自动重新启动?
如果你不能使用(正确的)init结构来做到这一点(你在共享主机等),使用cron来运行一个脚本(它可以用你喜欢的任何语言编写)检查它们是否正在运行,并在必要时重新启动它们。
您可以详细说明“使用(正确的)init结构来做到这一点”是什么以及如何解决确保脚本运行的问题? – 2008-09-22 13:35:00
TBH,PHP可能不是最好的工具,真的不是它的设计目的。当您尝试此操作时,我听说过内存泄漏和其他不好的事情。另外请记住,每次执行脚本时,PHP只有有限的资源id(用于文件句柄,db连接等)。
更好的使用别的东西,可能是python或perl,虽然我没有任何写这些应用程序的真实经验,但我知道PHP并不适合你的尝试。
不要试图听起来粗鲁,你应该删除这个答案,它显示了巨大的错误信息和缺乏知识水平。 “有限数量的资源ID”由操作系统处理,而不是由PHP处理。因此任何其他语言都会有完全相同的限制。看到PHP使用与C语言相同的库进行过程控制,您可以详细说明为什么它不适合它,看到您拥有与C完全相同的功能。我了解对某种特定语言的不满,但我无法理解故意传播的错误信息。 – 2014-08-18 19:44:12
我已经成功运行wget并将结果发送到共享服务器上的/ dev/null。
快速而肮脏的cron来重新启动守护进程:
* * * * * USER ps auxww | grep SCRIPTNAME > /dev/null || SCRIPTNAME
与守护进程运行作为和SCRIPTNAME与脚本的名称的用户替换用户。坚持这个在/etc/cron.d/restart_php_daemon
。它应该每分钟运行一次。将第一个*
更改为*/2
或*/5
以降低运行频率。
UPDATE
如果你把这个变成你自己的crontab:
运行crontab -e
并添加:
* * * * * ps auxwww | grep SCRIPTNAME > /dev/null || SCRIPTNAME
我使用一个基于PHP脚本从数据库中读取并发送电子邮件(使用PEAR Mail_Queue库)。我从bash脚本中运行它,并基于返回的结果(来自“exit $ status;”)停止,休眠X秒或立即重新启动。 (我还将负载平均值/睡眠状态检查到PHP脚本中,以避免对邮件系统造成压力)。
如果它是一个必须持续运行的长期守护,那么我同意,它可能不会是运行这个(虽然我听说没有成功运行长期一些插槽服务器的最好的事情),但是PHP 5.3现在也改进了垃圾回收机制,如果脚本写得足够好,不会退出计划外,那么内存应该远不如以前那样。
我们通过将输出传递给邮件来运行我们的守护进程。
php daemon.php | mail -s "daemon stopped" [email protected]
这样,当/如果守护程序停止,它将发送一封邮件,我们将会以这种方式通知。
它仍然意味着手动重启守护进程当然,但我们马上就会知道。通常,如果守护进程停止,则意味着还有其他事情需要照顾,所以这通常是可以的。
我同意PHP不是最好的工具,但我可以理解你为什么要使用PHP,所以你可以重用应用程序中的组件,比如数据库访问等等。
我有一个类似的问题,我最终开发了Fat Controller,它是一个用C编写的可以运行PHP脚本的守护进程。它也可以作为多线程守护进程运行,并行运行多个脚本实例。
这里有更多的信息和使用情况:http://www.4pmp.com/fatcontroller/
守护进程是一个在后台运行的Linux进程; apache或mysql是守护进程。 在linux环境中,我们可以使用cronjob运行后台程序,但它有一些限制,在某些情况下,这不是一个好主意。 例如,使用cronjob,我们无法控制之前的运行是否已完成。 因此,通常将进程作为守护进程运行会更方便。
// Daemonize
$pid = pcntl_fork(); // parent gets the child PID and child gets 0
if($pid){ // if pid is not 0
// Only the parent will know the PID. Kids aren't self-aware
// Parent says goodbye!
print "Parent : " . getmypid() . " exiting\n";
exit();
}
print "Child : " . getmypid() . "\n";
上面的代码是从有关如何在PHP创建一个守护进程非常好的文章服用。你可以阅读link
最好的和唯一的方法是过程监督。它围绕着父母的进程分派一个孩子并抓住它的退出信号。如果退出信号不好,请重新启动子进程。如果孩子死亡,父母(主管)将重新启动。为这个问题提供的所有答案在最好情况下都是不好的,因为没有一个人提到主管。 – 2014-08-18 19:46:57