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