为什么连续运行PHP脚本太糟糕了?

时间:2011-03-20 22:53:37

标签: php command-line cron infinite-loop

我有一张地图。在这张地图上,我想显示从几个表中收集的实时数据,其中一些表有惊人的行数。不用说,获取此信息需要时间。此外,涉及ping。根据脱机或远程服务器的不同,此数据的收集时间可能在1到10分钟之间。

我希望地图能够快速响应,所以我决定在我的数据库中添加一个新表,其中只包含地图所需的数据。这意味着我需要一个后台进程来持续更新新表中的信息。 Cron作业当然是可能的,但我希望在前一个间隔完成后立即刷新数据。如果离线IP地址的数量突然激增并且循环运行的时间比Cron作业的间隔长,该怎么办?

我自己的解决方案是在PHP中创建一个由命令行运行的无限循环。此循环将刷新映射到MySQL的数据,并记录其他有用的数据,如循环时间和ping等失败尝试,然后在短暂暂停(几秒钟)后重新启动。

但是 - 人们一再告诉我,永远运行的PHP脚本是不好的。过了一会儿它会占用数十亿字节的RAM(和其他可怕的东西)

部分我正在写这个问题以确认这是否实际上是这样的,但是关于如何编写一个不泄漏内存的干净循环(如果可能的话)的一些提示和技巧不会去吧。关于此事的意见也将受到赞赏。

我觉得答案对我将标记为正确的问题最为清楚。

5 个答案:

答案 0 :(得分:4)

循环应该在一个脚本中,它将激活/调用实际脚本作为一个不同的进程......就像cron正在做的那样。
这样,即使内存泄漏,并且未收集的内存正在累积,它也将/应该在每个周期后自由。

答案 1 :(得分:2)

  

但是 - 人们一再告诉我,永远运行的PHP脚本是不好的。过了一会儿它会占用数十亿字节的RAM(和其他可怕的东西)

这曾经是非常真实的。以前版本的PHP有可怕的 garbage collection,因此长时间运行的脚本很容易意外消耗比实际使用的内存更多的内存。 PHP 5.3 introduced a new garbage collector可以理解和清理循环引用,这是“内存泄漏”的首要原因。它默认启用。查看该链接以获取更多信息和漂亮的图表。

只要您的代码采取措施允许变量在适当的时间超出范围,否则取消设置将不再使用的变量,您的脚本不应仅仅因为它是PHP而消耗不必要的内存量。

答案 2 :(得分:1)

我不认为这很糟糕,就像你想要连续运行的任何东西一样,你必须要小心。

有些图书馆可以帮助您完成任务。看看System_Daemon,它在一个多月前发布RC 1,它允许您“设置最大RAM使用率等选项”。

答案 3 :(得分:1)

我没有运行无限循环,而是想要使用你提到的cron选项以及用于存储“当前活动”状态位的数据库表条目或平面文件,以确保你没有尝试同时运行的重叠进程。

虽然我意识到在执行下一次迭代之前这意味着一个小的延迟,但这可能是一个更好的主意:

  1. 它会让RDBMS执行任何待处理的低优先级更新等,由于您一直在执行的活动量,这些更新可能已暂停。

  2. 即使你整齐地取消了你一直在使用的所有临时变量,PHP仍然可能“泄漏”内存,尽管最近的改进(5.2引入了新的内存管理系统和垃圾收集在5.3中进行了彻底检查)希望意味着这不是一个问题。

  3. 一般来说,如果使用cron方法,处理其他问题(如果数据库连接由于配置更改而暂时关闭,例如重启)也会更容易,尽管在理想的世界中你会无论如何,要满足你的代码中的这种可能性。 (也就是说,我最后一次检查时,这远非一个理想的世界。)

答案 4 :(得分:0)

首先,我没有看到你需要一个守护进程脚本来提供你描述的功能。

  

Cron工作当然是可能的,但我希望在上一个间隔完成后立即刷新数据

cron作业和守护进程都不是解决问题的方法(除非守护进程成为脚本的数据接收器)。当数据可用,使用锁定策略来避免并发时,我会产生一个分离的进程。

长时间运行的PHP脚本本身并不坏 - 但引用计数垃圾收集器并不处理清理内存的所有可能方案 - 但是最近的实现有一个更高级的收集器,它应该清理更多(循环引用检查器) )。