我正在运行一个大的PHP脚本,它可能需要一整天来完成它的工作,
这个脚本从MySQL数据库中获取数据并将其与curl一起用来测试东西......它用 40,000 记录来实现..
因此,为了使它在后台运行,只要它需要,我使用终端执行它..在PHP脚本本身它有这些设置,以确保它运行尽可能长,直到它完成:
set_time_limit(0); // run without timeout limit
因为我从另一个单独的PHP脚本执行它,所以我使用这个函数
ignore_user_abort(1); // ignore my abort
因为直接从命令行执行它,它会给我两个选择..
1)等到脚本完成2)取消整个过程
在搜索之后,有一篇文章给了我第三个选择,它可以在后台运行它,尽可能通过创建一个外部PHP脚本来在后台执行主要的BIG PHP脚本这个功能:
exec("php bigfile.php");
这意味着我可以正常地从浏览器打开此外部页面并毫无顾虑地退出,因为ignore_user_abort
将使其在后台运行.. 这仍然不是问题
问题是......在一段未知的时间之后,脚本停止工作.. 我怎么知道?我告诉它在外部文件中写下它工作的每条记录的当前日期时间在,所以我每次刷新到该外部页面,看它是否停止更新,
在一个未知的时期之后它实际上没有任何理由停止,脚本没有任何说停止或任何东西..如果发生任何错误,我告诉它跳过记录(没有错误发生,他们都在同一工作如果一个人工作,那么所有人都应该工作)
然而,我的主要疑虑如下:
while
向PHP循环提供记录?如果发生错误,它会崩溃整个脚本吗?在崩溃整个脚本的任何事情上是否有任何超时? 如果这些都不适用于它,有没有办法记录脚本现在正在发生什么?或者为什么会崩溃?记录所有内容的详细方法?
<小时/> 更新:
我在messages
中的/var/log/
文件中找到了这个:
Dec 29 16:29:56 i0sa shutdown[5609]: shutting down for system halt
Dec 29 16:30:14 i0sa exiting on signal 15
Dec 29 16:30:28 i0sa syslogd 1.5.0#6: restart.
Dec 29 16:50:28 i0sa -- MARK --
.....
Dec 29 18:50:31 i0sa -- MARK --
Dec 29 19:02:36 i0sa shutdown[3641]: shutting down for system halt
Dec 29 19:03:11 i0sa exiting on signal 15
Dec 29 19:03:48 i0sa syslogd 1.5.0#6: restart.
它说系统暂停..我会尽力确保这可能是在未来的崩溃和匹配时间,这可能导致它?为什么? memory_limit
是128M而我有2GB
服务器内存ram,这可能是吗?
P.S。:我手动多次重启服务器..但是这个说关机并停止了?
答案 0 :(得分:5)
对于这种情况,我使用成功nohup命令,如下所示:
nohup php /home/cron.php >/dev/null 2>&1 &
如果脚本运行时,您可以检查:
jobs -l
注意: 当您使用nohup命令路径时,php文件必须绝对不是相对的。 我认为从一个php文件调用另一个php文件只是为了防止执行在完成工作之前停止是不是很优雅。
外部参考: http://en.wikipedia.org/wiki/Nohup
还要确保脚本中没有内存泄漏,这会导致脚本在一段时间后崩溃,因为“内存不足”。
答案 1 :(得分:2)
你尝试过使用nohup吗?
exec("nohup php bigfile.php &");
如果你的主机允许nohup命令,那么命令应该在后台运行,并且调用exec的脚本应该立即继续。
答案 2 :(得分:1)
Osa,你的Apache很可能已经杀了这个,我可以详细了解可能的原因,正如其他人肯定会的那样。
我宁愿回答您的问题,而不是您的问题,并建议您使用tmux
来完成您描述的任务(或screen
如果tmux
不可用)。
所以你要做的就是打开tmux
并从那里开始编写脚本。与ctrl-b d
分离,稍后与tmux attach
重新合并以查看它有多远。分离时,您可以在不停止的情况下退出。
简要介绍其他tmux
内容,您还不需要,但可以帮助您了解方法http://victorquinn.com/blog/2011/06/20/tmux/
或以后
http://blog.hawkhost.com/2010/06/28/tmux-the-terminal-multiplexer/非常好
答案 3 :(得分:0)
执行时间不是唯一要考虑的事情。接下来可能的罪魁祸首是脚本超过max_memory_limit
您是否检查/启用了错误记录?可能会默默地失败。
答案 4 :(得分:0)
如果您使用Apache,则会有大约300秒的超时。定期调用apache_reset_timeout();
可以允许脚本永久运行,如果你不停止它。
答案 5 :(得分:0)
首先我遇到了这个问题并解决但我想强调你的MySQL服务器不负责这个挂起只需要在Apache中更改一些设置。在PHP文件的上面这些下面的行
ini_set('max_execution_time', 1000);
ini_set('memory_limit', '50M');
set_time_limit(0);
并且每个提取数据应使用:
$url_class = $URL_path;
//open connection
$ch_school_class = curl_init();
curl_setopt($ch_school_class, CURLOPT_URL, $url_class);
$result_school_class = curl_exec($ch_school_class);
//clean up
curl_close($ch_school_class);
//Each fetch like this
$url_class = $URL_path;
//open connection
$ch_school_class = curl_init();
curl_setopt($ch_school_class, CURLOPT_URL, $url_class);
$result_school_class = curl_exec($ch_school_class);
//clean up
curl_close($ch_school_class);
答案 6 :(得分:0)
1:考虑使用popen(),pclose()等在外部运行PHP脚本。
2:您可以使用multi curl handler
缩短cURL请求的长度3:如果可能,您应该尝试使用其他语言。众所周知,PHP对于较大的任务来说相当慢。为什么全部花费一整天才能在最短的几个小时内完成(我说几个小时,因为它必须向40,000个不同的地址发出网络请求)
4:并且,正如许多其他人所说的那样,如果可以,请尝试使用nohup。
答案 7 :(得分:0)
使用ignore_user_abort通过apache运行长时间运行的脚本是一种肮脏的方法。
最简单的方法是使用 GNU屏幕,只需键入屏幕,然后您将连接到当前控制台内的新控制台,启动脚本,然后使用 ctrl从屏幕上分离-a d (完整的手动here),即使您与服务器断开连接,屏幕仍会继续工作。
要重新连接到您的屏幕,请使用 screen -r ,然后您将返回正在运行的脚本。
最难的方式(也是最干净的方法)是重写你的脚本以作为系统守护进程工作,有很多lib可以帮助你做到这一点,我建议你挖掘一下pear的守护进程lib(例子{{ 3}})。
至于内存限制问题(?),在决定更新memory_limit配置之前,你必须检查你的脚本是否比你当前配置中写的更多ram,做一个简单的 ps aux | grep php 并查找 RSS 列,这是您的脚本正在吃的所有内存。
答案 8 :(得分:0)
我们通常面临许多其他问题。