0

我有一个脚本,它从服务器流式传输文件并将收集的数据一次保存为小块,以防止内存溢出,在主机服务器上。

我有没有提到它是一个 PHP 脚本?

这就是它的工作原理

//loop while data exists on the clients server side file.
while (!feof($xml_fp)) {

                   //grab data in proportions of specified chunk
                   //write the the collected chunk locally
                    //if there's an error, exit (improve error handling for final code)


             $result =  fwrite($local_fp, fread($xml_fp, $size), $size);

                   if($result === false){
        echo"<h1> ERROR </h1>";
        exit(); 
                            }

                   else    {
                $progress += $result;
                ob_flush(); 
                flush(); 
                ?>
               //state amount of data downloaded thus far
                <script>
                $('#progress').html(' ');
                $('#progress').append(<?php echo (float)$progress/(1024*1024) ?>);
                </script>
                <?php

             //if all goes well, increase time limit by a second
                set_time_limit(1);

                     }
}//while loop ends here

该脚本在本地运行良好。我将不得不在具有不同大小文件的实时服务器上运行大量测试,以确保没有任何问题,但是文件大小可以从 50mb 到 200mb 不等。

请记住 fread 和 fwrite 函数的开销很大,我预计下载速率不会超过 40 kbps,并且我估计的平均下载时间因此脚本运行的持续时间约为 10 分钟。

问题:服务器是否通常配置为在检测到这么长的脚本运行时间时调用犯规?请注意,这不是专用服务器,只是磨机共享资源的运行,因此我无法通过 execute() 调用等使用 wget 启动相同的服务器。

4

3 回答 3

1

这可能归结为这个电话:

//if all goes well, increase time limit by a second
set_time_limit(1);

这个评论是不正确的。这将使脚本在调用 set_time_limit 时开始运行。增加一点可能是值得的。

于 2012-08-17T16:39:27.950 回答
1

这取决于您如何运行 PHP。

您需要立即查看max_execution_time,文档还指出

您的 Web 服务器可以有其他可能会中断 PHP 执行的超时配置。Apache 有一个 Timeout 指令,而 IIS 有一个 CGI 超时功能。两者都默认为 300 秒。有关特定详细信息,请参阅您的 Web 服务器文档。

如果您通过 fcgi 运行 PHP,您还需要在那里调整超时。

编辑

您是否考虑过询问您的共享托管服务提供商?

于 2012-08-17T16:53:33.950 回答
1

上面的答案是正确的,但是一些服务器(例如 apache)有脚本,可以终止长时间运行的 php 脚本,而不管 apache 配置中设置的 execution_time。

我通过从 php 脚本中启动 php_cli 进程解决了类似的问题(发送电子邮件通讯数小时)。如果您的主机支持它,这是处理这类事情的一种非常可靠的方式。

另一种非常好的方法是将加载时间分散到多个页面上。这可以通过在脚本上设置ignore_user_abort并在获取单个块并退出后使用 curl 调用其自己的 URL 来完成。

对于这两种方法,您都需要一个类似的方法来限制单个进程的执行时间:即使 CLI 和 Apache 都应该支持永久运行的脚本,但我发现它们会在一段时间后停止。这两种方法都类似于接力赛:跑 100 米,然后将工作交给下一个工人跑,等等。

要查看我是如何处理时事通讯的,代码在 github 上

于 2012-08-19T22:22:07.823 回答