我正在尝试找出每天运行数千次一个相当繁重的PHP任务的最有效方法。该任务需要与Gmail建立IMAP连接,遍历电子邮件,将这些信息保存到数据库中并将图像保存在本地。
使用cron定时运行此任务不是什么大问题,但我需要每分钟运行一次它,并且我知道最终cron会开始互相覆盖并导致内存问题。
当您需要高效地多次运行任务时,请采取下一步措施是什么?我一直在阅读有关beanstalk和pheanstalk的文章,但我并不确定它是否能够满足我的需求。 你有什么想法吗?
我正在尝试找出每天运行数千次一个相当繁重的PHP任务的最有效方法。该任务需要与Gmail建立IMAP连接,遍历电子邮件,将这些信息保存到数据库中并将图像保存在本地。
使用cron定时运行此任务不是什么大问题,但我需要每分钟运行一次它,并且我知道最终cron会开始互相覆盖并导致内存问题。
当您需要高效地多次运行任务时,请采取下一步措施是什么?我一直在阅读有关beanstalk和pheanstalk的文章,但我并不确定它是否能够满足我的需求。 你有什么想法吗?
我不是PHP专家,但是......有什么阻止你将脚本作为守护进程运行呢?我曾经编写过很多这样的perl脚本。
我不是PHP开发者,但是......有什么防止你将脚本作为守护进程运行的问题吗?我编写过许多类似的perl脚本。while(1)
中,并将脚本在后台运行即可。如果它完成某些事情比仅仅被杀掉更重要,那么请了解信号处理,这样你就可以在退出之前进行清理。如果能使用 fork 而不是在 shell 后台运行,则会额外加分 :) - Brian Roach要么创建一个锁定机制,以使脚本不会重叠。由于脚本仅在每分钟运行一次,因此一个简单的.lock文件就足够了:
<?php
if (file_exists("foo.lock")) exit(0);
file_put_contents("foo.lock", getmypid());
do_stuff_here();
unlink("foo.lock");
?>
这将确保脚本不同时运行,您只需要确保在程序退出时删除.lock文件,因此您应该有一个单独的退出点(除了开始时的退出)。
另一个好的选择——就像Brian Roach建议的那样——是一个专用的服务器进程,它始终运行并保持与IMAP服务器的连接。 这大大降低了开销,并且与编写常规php脚本几乎没有区别:
<?php
connect();
while (is_world_not_invaded_by_aliens())
{
get_mails();
get_images();
sleep(time_to_next_check());
}
disconnect();
?>
我有一些类似这样的脚本,我不想在cron中运行它们以防堆积。
#!/bin/sh
php -f fetchFromImap.php
sleep 60
exec $0
exec $0
部分会重新启动脚本,将自己替换在内存中,这样它就可以一直运行而不会出问题。PHP脚本使用的任何内存都会在退出时清理,因此也不是问题。cd /x/y/z ; nohup ./loopToFetchMail.sh &
或者可以通过各种方式(例如Cron的“@reboot ....”)在机器启动时类似地启动。