【问题标题】:What do I use when a cron job isn't enough? (php)当 cron 作业不够时,我该使用什么? (php)
【发布时间】:2010-04-21 06:10:33
【问题描述】:

我正在尝试找出每天数千次运行相当繁重的 PHP 任务的最有效方法。它需要与 Gmail 建立 IMAP 连接,遍历电子邮件,将此信息保存到数据库并在本地保存图像。

使用 cron 经常运行这个任务并不是什么大不了的事,但我需要每分钟运行一次,而且我知道这些 cron 最终会开始相互叠加运行并导致内存问题。

当您需要在一分钟内高效地运行一项任务时,下一步是什么?我一直在阅读有关 beantalk 和 pheanstalk 的文章,但我不完全确定这是否能满足我的需要。想法???

【问题讨论】:

  • 这与您的问题没有直接关系,而是使用 CURL 来检索图像。它缓存 DNS 请求,而 file_get_contents() 和其他本机文件函数不缓存。我曾经需要编写一个脚本来检索图像,而几乎所有的执行时间都是网络延迟。所以这可以帮助减少它。

标签: php cron beanstalkd


【解决方案1】:

我不是 PHP 专家,但是……是什么阻止您将脚本作为守护程序运行?我已经编写了许多执行此操作的 perl 脚本。

【讨论】:

  • 我以前从未编写过守护程序,但我现在将开始做更多的研究。感谢您的建议。
  • 基本上......您只需将所有内容包装在while(1) 中并在后台运行脚本。如果重要的是它完成某事而不是仅仅被杀死,请查看信号处理,以便您可以在退出之前进行清理。分叉的奖励积分,而不是要求它从后台的 shell 运行:)
  • 我建议 2 个文件:第一个文件创建另一个运行守护进程的进程。第一个将等待几秒钟并检查守护程序是否仍在运行。如果没有,它可以重新启动它。我不太信任 PHP 运行这么长时间,所以我认为还是采取预防措施比较好。
  • PHP 脚本在长时间运行时没有问题,我们这里的脚本可以运行数周而没有问题。您不必喜欢 PHP(我不喜欢),但该语言已经成熟了很多,现在相当稳定。
  • @Brian Roach:我相信 PHP 历来比 Perl 有更多的内存泄漏问题。那,当然还有重视你的理智:)
【解决方案2】:

或者创建一个锁定机制,这样脚本就不会重叠。这很简单,因为脚本只每分钟运行一次,一个简单的 .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();
?>

【讨论】:

  • 我认为守护进程将是我最好的选择,保持 IMAP 开放应该会让事情变得更快。感谢您的建议!
【解决方案3】:

我有很多这样的脚本,我不想从 cron 运行它们以防它们叠加。

#!/bin/sh
php -f fetchFromImap.php
sleep 60
exec $0

exec $0 部分重新启动脚本运行,在内存中替换自身,因此它将永远运行而不会出现问题。 PHP 脚本使用的任何内存在退出时都会被清理,所以这也不是问题。

一个简单的行将启动它,并把它放到后台:

cd /x/y/z ; nohup ./loopToFetchMail.sh &

或者机器启动时也可以类似的启动方式(比如Cron的'@reboot ....')

【讨论】:

    【解决方案4】:

    如果旧任务仍在运行,fcron http://fcron.free.fr/ 将不会开始新任务,您可以使用 @ 1 command 而不必担心竞争条件。

    【讨论】:

      猜你喜欢
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多