【问题标题】:Run cron job every 10 seconds n times then stop每 10 秒运行一次 cron 作业 n 次,然后停止
【发布时间】:2010-10-12 09:34:32
【问题描述】:

我有一个特殊的情况,我需要查询一个服务来获取每天特定时间的 n 个用户的信息。问题是,如果我一次完成这一切,它会使服务脱机/崩溃。

所以要克服这个问题,最好每 10 秒左右为 x 个用户运行一次,直到 x = n 然后停止。

我可以设置 1 个每天运行的 cron 脚本和另一个每 10 秒运行一次的脚本。例如,每日脚本会将数据库中的值设置为 1(“开始查询”)(默认值为 0 表示关闭),然后第二个脚本(每 10 秒运行一次)检查该数据库值是否为 1。设置为 true 然后遍历用户一次查询服务 x 个用户并增加同一个 DB 表中的另一列以跟踪它在列表中的位置。

这个解决方案的问题(在我看来很好)是每 10 秒运行的第二个脚本每次都必须查询数据库,以确定“开始查询”设置是否设置为 1。这可能是一个相当处理器重的。谁有更好的解决方案?

注意:代码是用 PHP 编写的 - 由于服务器上 php 脚本的执行时间最长,因此无法使用睡眠

我在 python 中同样可以做到这一点,cgi 脚本是否有最大执行限制?

【问题讨论】:

标签: php cron


【解决方案1】:

为什么不每天运行一个 cron 脚本,然后每隔十秒调用另一个脚本,直到另一个脚本说它已完成(例如,返回一个表示“没有更多需要处理”的值)?

或者一个每天运行的脚本,只是在循环中遍历大量用户,让每个 X 用户休眠()...

请记住,使用CLI version of PHP 时,您不受执行时间限制,并且可以使用标准错误和输出流等很好地与 cron 和其他 shell 脚本进行交互。

例如,对于第一种方法,您甚至不必将 PHP 用于“控制”脚本 - 一个非常简单的 shell 脚本,它只是循环、调用您的 PHP 脚本然后休眠,并检查“成功”返回值(由 PHP 脚本的 exit() 函数返回)就可以了。

【讨论】:

  • PHP 脚本没有最大执行时间吗?如果我使用睡眠,那么最长执行时间将需要设置为几小时……这不是一个好习惯——我怎样才能让一个脚本每 10 秒调用另一个脚本而不使用你在第一段中提到的睡眠?跨度>
  • @Martin 如果您使用的是CLI version of PHP,则不应遇到执行时间限制(请参阅this article 以获得温和的介绍)。
【解决方案2】:

您可以将“at”与“cron”结合使用。设置一个每天运行一次任务的 cron 作业,该任务是(我面前没有 UNIX 盒子,所以可能会出现奇怪的语法错误)。

0 9 * * * at now + 10 secs /path/to/shellscript 1

参数是运行计数。当 shellscript 运行时,它会重新安排自己的运行时间,增加运行次数,因此您可以:

#!/bin/ksh

integer i
let i=1+$1
if [[ $i -lt 11 ]]
then
    at now + 10 secs /path/to/shellscript $i

    # do everything else the script needs to do
fi

注意:此解决方案还假设“at”可以下降到每秒次数(不确定这是否可能;可能取决于实施)。如果不是这样,这个解决方案可能一开始就无效:-)在这种情况下,你最好有一个脚本来做事和睡觉(根据马特吉布森的回答)。

【讨论】:

    【解决方案3】:

    有多种方法:

    • 拥有一个运行部分作业的脚本,将所有数据放入一个变量中,您可以对数据和状态进行序列化。我已经为代码点火器实现了一个调度程序控制器,以便在 http://www.younelan.com/index.php?&repository=DCExplorer 时获取一条地铁路线。它可能比您所看到的更复杂,但可能会让您了解如何以不同的时间间隔运行多个任务,将它们分解成更小的部分
    • 通过 cron 或手动从命令行运行脚本 - 不会出现超时问题

    【讨论】:

    • 感谢您发布您的答案!请务必仔细阅读FAQ on Self-Promotion。另请注意,每次链接到自己的网站/产品时,都要求发布免责声明。