我希望创建一个后台进程,我被告知这些通常是用C语言编写的。我最近发现PHP可以用来创建一个守护进程,我希望得到一些建议,如果我应该以这种方式使用PHP。
以下是我对守护程序的要求。
我不确定我能提供什么来帮助做出这个决定。只是补充一下,我之前没有做过C。只有Java和PHP以及基本的bash脚本。
它甚至会产生很大的性能差异吗?
请允许我的无知,我正在学习! :)
全部谢谢
答案 0 :(得分:29)
正如其他人所说,各种版本的PHP都有垃圾收集器的问题。当然,如果您知道您的版本没有此类问题,则可以消除该问题。关键是,你不知道(肯定),直到你编写守护进程并通过valgrind运行它,看看安装的PHP是否在任何给定的机器上泄漏。所以在这一方面,你可以写它只是为了发现Zend认为修复的东西可能仍然是错误的,或者你正在处理稍微旧版本的PHP或某些扩展。恶心。
另一个问题是有些错误的信号。根据我的经验,信号处理程序并不总是用PHP正确输入,特别是当信号排队而不是合并时。这对您来说可能不是问题,即如果您只需要处理SIGINT / SIGUSR1 / SIGUSR2 / SIGHUP。
所以,我建议:
如果守护进程很简单,请继续使用PHP。如果看起来它会变得相当复杂,或者分配大量内存,你可以考虑在用PHP进行原型设计之后用C语言编写它。
我是一个非常死的C人。但是,我认为用PHP快速敲击一些东西是没有错的(除了我解释过的情况)。我也发现使用PHP来构建可能会或可能不会在C中重写的东西也没有错。例如,如果使用PHP,处理数据库的东西会更简单,而不是使用C中的其他接口来管理回调。所以在那个例子,对于'一次性',你肯定会更快地完成它。
答案 1 :(得分:17)
我倾向于使用cron作业执行此任务,而不是在守护程序中轮询数据库。
你的FFmpeg命令可能需要一段时间才能完成它,对吧?在这种情况下,是否真的必须不断轮询数据库?每一分钟(或者每五分钟,十分钟或二十分钟)运行的cronjob不是更简单的方法来实现同样的目标吗?
答案 2 :(得分:7)
唯一的缺点是php并不像perl或python那样无处不在,它几乎安装在unix上。 Php只能在将要提供动态Web内容的系统上找到。并不是说Php解释器的安装太大或太昂贵,但如果你最关心的是让你的程序进入许多系统,这可能是一个小障碍。
答案 3 :(得分:6)
我会反对并建议你试试php守护进程。这显然是你认识最好的语言。在任何情况下,您都可能会使用计时器,因此您可以在数据库上复制查询频率。只要你没有天真地循环查询,就没有任何惩罚。
如果它不经常执行,你可以从cron运行php,让你的代码耗尽队列然后死掉。
但是,不要害怕坚持你最了解的东西,作为第一个近似值。
尽量不要使用触发器。它们会产生不必要的耦合,测试和调试它们并不好玩。
答案 4 :(得分:4)
正确守护PHP脚本的一个问题是PHP没有与dup()或dup2()系统调用的接口,这些是分离文件描述符所必需的。
答案 5 :(得分:3)
如果不需要近乎即时的操作,cron-job可能会正常工作。
我正准备将基于排队守护进程'beanstalkd'的系统建立起来。我从(在这种情况下,PHP)网页调用发送各种小消息到守护进程,然后PHP脚本从队列中拾取它们并执行各种任务,例如调整图像大小或检查数据库(通常通过Memcache传回信息)的商店)。
为了避免长时间运行的进程,我将它包装在一个BASH脚本中,根据脚本返回的值(“exit(1);”)将重新启动脚本,对于每个(例如)50它执行的任务。如果它正在重新启动,因为我计划它,它将立即执行,任何其他退出值(默认值为0,所以我不使用它)将在重新启动之前暂停几秒钟。
答案 6 :(得分:2)
作为一个具有明确周期性的cron作业运行,PHP脚本可以完成这项工作,并且生产稳定性当然是可以实现的。您可能希望限制同时FFMpeg实例的数量,并确保具有完整的应用程序日志记录和异常处理。我已经在Java中实现了连续运行的轮询过程,以及每十分钟一次的cron'd PHP脚本,并且两者都很好地完成了工作。
答案 7 :(得分:1)
您可能需要考虑创建一个执行trigger命令(即FFmpeg)而不是守护进程的mysql system。如果某些延迟不是问题,您还可以在cron中放入一些每隔几分钟执行一次检查的内容。如果是选项,Cron将是我的选择。
要回答你的问题,php完全可以作为守护进程运行。它不必在C中完成。
答案 8 :(得分:1)
如果你结合Kent Fredric,tokenmacguy和Domster的答案,你会得到一些有用的东西。
php可能不适合执行时间长, 所以让我们保持每个执行周期都很短,并确保操作系统负责清理任何内存泄漏。 作为启动PHP脚本的工具,cron可以成为一个很好的工具。 如果你这样做,语言之间没有太大的区别。
但问题仍然存在。 php是否能够长时间(几年)作为普通守护进程运行? 或者各种记忆泄漏会占用你所有的公羊并杀死系统?
/约翰
答案 9 :(得分:1)
如果这样做,请注意内存泄漏。根据{{3}}(在5.3中修复),PHP 5.2的垃圾收集器存在一些问题。也许最好使用cron,因此脚本每次运行都会开始清理。
答案 10 :(得分:1)
如果您决定沿着守护程序路线走下去,那么我最近在PHP v5.3.0安装上成功使用了一个名为 System_Daemon
的PEAR模块。它在作者博客上有记录:http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php
如果安装了PEAR,则可以使用以下命令安装此模块:
pear install -f System_Daemon
您还需要创建初始化脚本:/etc/init.d/<your_daemon_name>
然后你可以:
/etc/init.d/projNotifMailDaemon start
/etc/init.d/projNotifMailDaemon stop
日志保存在:/var/log/<your_daemon_name>.log
答案 11 :(得分:1)
对于你所描述的内容,我会选择一个守护进程。确保在轮询循环中保持睡眠状态,这样在没有新任务时就不会轰炸数据库。 cronjob更适用于工作流/报告类型的作业,其中没有某些特定事件会触发下一次运行。
如上所述,PHP在内存管理方面存在一些问题。您需要确保测试代码是否存在内存泄漏,因为这些代码会在长时间运行的脚本中随着时间的推移而累积。 PHP没有真正的垃圾收集 - 它依赖于引用计数,这意味着循环引用将导致泄漏。如果你意识到这一点,你可以围绕它进行编码。
答案 12 :(得分:0)
如果你知道你在做什么。您需要很好地了解您的操作系统。 PHP通常不适合大多数守护进程,因为它没有线程,并且没有适合所有任务的基于事件的系统。但是,如果它适合您的需求那么没问题。现代PHP(5.3+)非常稳定,没有任何内存泄漏。只要您启用GC并且不实现自己的内存泄漏等,您就可以了。
以下是我正在运行的一个守护程序的统计信息: 正常运行时间为17天(由于PHP升级,最后一次重启)。 写入的字节数:200GB 连接:数百 连接处理,数十万 处理的项目/请求:数百万
node.js通常更适合,虽然有一些小烦恼。已经尝试在相同领域改进PHP,但它们并不是那么好。
答案 13 :(得分:0)
我不推荐它。 PHP不是为长期执行而设计的。它主要设计为短期页面。
根据我的经验,PHP可能会出现一些较大任务泄漏内存的问题。
答案 14 :(得分:0)
一个cron作业和一些bash脚本应该是你需要的一切声音。你可以这样做:
$file=`mysqlquery -h server < "select file from table;"`
ffmpeg $file -fps 50 output.a etc.
所以bash比使用PHP更容易编写,移植和维护IMHO。
答案 15 :(得分:-2)
Cron的工作?是。
永远运行的守护进程?否。
PHP没有垃圾收集器(或者至少,我上次检查时没有)。因此,如果您创建循环引用,它永远不会被清除 - 至少在主脚本执行完成之前。在守护进程中,这几乎从不。
如果他们在新版本中添加了GC,那么您可以。
答案 16 :(得分:-5)
去吧。我也必须做一次。 像其他人说的那样,它并不理想,但它会完成。使用Windows,对吗?好。
如果您只需要偶尔运行(每小时一次等)。 为firefox创建一个新的快捷方式,将其放在相关的位置。 打开快捷方式的属性,将“目标”更改为:
"C:\Program Files\Mozilla Firefox\firefox.exe" http://localhost/path/to/script.php
转到“控制面板”&gt;“计划任务” 将新计划任务指向快捷方式。
如果你需要它不断运行或伪持续,你需要稍微调整一下脚本。
使用
启动脚本set_time_limit(0);
ob_implicit_flush(true);
如果脚本使用循环(如而),则必须清除缓冲区:
$i=0;
while($i<sizeof($my_array)){
//do stuff
flush();
ob_clean();
sleep(17);
$i++;
}