为什么连续运行PHP脚本如此糟糕?

为什么连续运行PHP脚本如此糟糕?,php,command-line,cron,infinite-loop,Php,Command Line,Cron,Infinite Loop,我有一张地图。在这张地图上,我想展示从几个表中收集的实时数据,其中一些表的行数惊人。不用说,获取这些信息需要很长时间。此外,ping也参与其中。根据服务器处于脱机状态或距离较远,此数据的收集时间可能在1到10分钟之间 我希望地图能够快速响应,因此我决定向数据库中添加一个新表,其中只包含地图所需的数据。这意味着我需要一个后台进程来不断更新新表中的信息。Cron作业当然是可能的,但我希望在上一个间隔完成后立即刷新数据。如果脱机IP地址的数量突然增加,循环运行的时间比Cron作业的时间间隔长,该怎么办

我有一张地图。在这张地图上,我想展示从几个表中收集的实时数据,其中一些表的行数惊人。不用说,获取这些信息需要很长时间。此外,ping也参与其中。根据服务器处于脱机状态或距离较远,此数据的收集时间可能在1到10分钟之间

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

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

然而,人们一再告诉我,永远运行PHP脚本是不好的。一段时间后,它将占用千兆字节的RAM(以及其他可怕的东西)

我写这个问题的部分原因是为了确认事实是否如此,但是关于如何编写一个不泄漏内存的干净循环(如果可能的话)的一些提示和技巧不会出错。对此事的意见也将不胜感激


我觉得这个回答最能说明我将标记为正确的问题。

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

然而,人们一再告诉我,永远运行PHP脚本是不好的。一段时间后,它将占用千兆字节的RAM(以及其他可怕的东西)

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


只要您的代码采取步骤允许变量在适当的时间超出范围,或者取消设置不再使用的变量,您的脚本就不应该因为是PHP而消耗不必要的内存。

我认为这并不坏,因为对于任何要连续运行的脚本,您必须更加小心


有一些库可以帮助您完成这项任务。看看一个多月前发布的RC 1,它允许您“设置选项,如最大RAM使用量”。

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

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

  • 它将允许RDBMS执行任何挂起的低优先级更新等,这些更新可能由于您执行的活动量而被搁置

  • 尽管最近的改进(5.2引入了一个新的内存管理系统,垃圾收集在5.3中进行了彻底的修改)有望减少这一问题,但即使您巧妙地取消了所有已使用的临时变量的设置,PHP仍有可能“泄漏”内存


  • 一般来说,如果您使用cron方法,那么处理其他问题(例如,如果数据库连接由于配置更改而暂时中断并重新启动)也会更容易,尽管在理想情况下,您还是可以在代码中处理此类事件。(也就是说,上次我检查时,这远远不是一个理想的世界。)

    首先,我看不出您如何需要守护程序脚本来提供您描述的功能

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

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


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

    一个难以置信的小问题,但请不要在问题中添加签名/签字。(除此之外,这是一个构造非常好的问题。):-)我想举个例子。你是说像这样的事吗?1.如果使用无限循环,只要每个间隔之间有一个停顿,情况不是也会如此吗?在我的例子中,这个脚本无论如何都会在专用服务器上运行。2.这可以通过运行一个PHP文件来解决吗?当循环时,执行另一个PHP文件一次,然后休息一下?@Codemonkey 1。对2.理论上是的。然而,我仍然有一种唠叨的感觉,那就是它不会那么可靠。也就是说,在事后将您提到的方法转换为使用cron是很简单的,所以这很可能是一条可行的道路。(即:尝试使用不同的“模式”方法生成PHP脚本自身的副本,如果发现随着时间的推移会降级,那么只需通过cron调用相同的脚本即可。)只要定期记录
    内存使用情况的结果<