我试图找出每天数千次运行相当庞大的 PHP 任务的最有效方法。它需要与 Gmail 建立 IMAP 连接,遍历电子邮件,将此信息保存到数据库并在本地保存图像。
经常使用 cron 运行这个任务并不是什么大不了的事,但我需要每分钟运行一次,而且我知道 cron 最终会开始相互叠加运行并导致内存问题。
当您需要在一分钟内多次高效地运行任务时,下一步是什么?我一直在阅读有关 beantalk 和 pheanstalk 的文章,但我不完全确定这是否能满足我的需要。想法???
我试图找出每天数千次运行相当庞大的 PHP 任务的最有效方法。它需要与 Gmail 建立 IMAP 连接,遍历电子邮件,将此信息保存到数据库并在本地保存图像。
经常使用 cron 运行这个任务并不是什么大不了的事,但我需要每分钟运行一次,而且我知道 cron 最终会开始相互叠加运行并导致内存问题。
当您需要在一分钟内多次高效地运行任务时,下一步是什么?我一直在阅读有关 beantalk 和 pheanstalk 的文章,但我不完全确定这是否能满足我的需要。想法???
我不是 PHP 人,但是……是什么阻止您将脚本作为守护进程运行?我已经编写了许多执行此操作的 perl 脚本。
要么创建一个锁定机制,这样脚本就不会重叠。这很简单,因为脚本只每分钟运行一次,一个简单的 .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 ....')
如果旧的仍在运行,fcron http://fcron.free.fr/@ 1 command
将不会开始新的工作,您可以使用而不必担心竞争条件。