如何每分钟更频繁地运行Cronjobs?

时间:2011-01-12 18:19:27

标签: php linux crontab

我创建了一个Email-Queue数据库表。我将插入我的PHP应用程序需要发送到此表的所有电子邮件。

然后,另一个PHP脚本将查找所有未发送的电子邮件并发送它们。

我使用cronjobs运行此脚本。不幸的是,cronjobs每分钟最多只能运行一次。 因此,在最坏的情况下,用户必须等待一分钟,直到他的电子邮件真的要发送。

我目前的解决方法是使用addtional sleep参数调用脚本并复制cronjobs。

示例:

* * * * * curl emails.php?sleep=0 >/dev/null 2>&1
* * * * * curl emails.php?sleep=10 >/dev/null 2>&1
* * * * * curl emails.php?sleep=20 >/dev/null 2>&1
* * * * * curl emails.php?sleep=30 >/dev/null 2>&1
* * * * * curl emails.php?sleep=40 >/dev/null 2>&1
* * * * * curl emails.php?sleep=50 >/dev/null 2>&1

在上面的示例中,脚本每10秒运行一次。 emails.php脚本的第一行是:

sleep($_REQUEST['sleep']);

6 个答案:

答案 0 :(得分:15)

这是我编写的一个简单的bash脚本,它可以与crontab一起使用,运行频率超过1分钟。

你可以把它保存为〜/ bin / runEvery.sh 然后在crontab中编写类似这样的内容,每隔5秒运行一次otherScript.sh:

*/1 * * * * ~/bin/runEvery.sh 5 otherScript.sh

这是剧本:

#!/bin/bash

inputPeriod=$1
runCommand=$2
RUN_TIME=60
error="no"

if [ 'x'"$runCommand" != 'x' ]
then
    if [ 'x'$inputPeriod != 'x' ]
    then
        loops=$(( $RUN_TIME / $inputPeriod ))
        if [ $loops -eq 0 ]
        then
            loops=1
        fi

        for i in $(eval echo {1..$loops})
        do
            $runCommand
            sleep $inputPeriod
        done

    else
        error="yes"
    fi
else
    error="yes"
fi

if [ $error = "yes" ]
then
    echo "runEvery - runs a command every X seconds for a minute"
    echo "Usage: runEvery.sh <# in seconds < 60> <command to run>"
fi

答案 1 :(得分:13)

这必须在脚本级别完成。

// cron.php running every 10 seconds

<?php

$expireTime = time() + 60;
while (time() < $expireTime) {
     // my php logic here

     sleep(10); 
     // sleep for 10 seconds
     // you may change the sleep time to change frequency
}

答案 2 :(得分:9)

对于初学者,我建议使用PHP的命令行版本而不是使用curl来调用脚本。然后,您可以创建一个具有合理生命周期的PHP脚本,该脚本不受必须在给定时间段内输出响应的限制。

因此,您可以在PHP脚本中简单地睡眠/检查电子邮件/传输/睡眠等,而不是不必要地使用cron。

此外,我要注意确保多个PHP脚本不能同时在数据库表上运行,方法是使用pid文件或数据库设置方法(如果存在/设置了给定的文件/设置) ,中止处理)或通过合理计时cron作业并限制脚本的最大处理时间,方法是在开始循环“检查电子邮件”部分之前检查它运行了多长时间。

答案 3 :(得分:2)

怎么样:

* * * * * sleep 10 ; curl emails.php?sleep=0 >/dev/null 2>&1
* * * * * sleep 20 ; curl emails.php?sleep=0 >/dev/null 2>&1
* * * * * sleep 30 ; curl emails.php?sleep=0 >/dev/null 2>&1
* * * * * sleep 40 ; curl emails.php?sleep=0 >/dev/null 2>&1
* * * * * sleep 50 ; curl emails.php?sleep=0 >/dev/null 2>&1

答案 4 :(得分:1)

如果每10秒钟执行一次,那么cron就不适合这项工作。你需要的是一个连续运行的脚本,如Ish所示。

您可以通过将相应的启动/停止脚本放入/etc/init.d并启用它来将脚本注册为服务。

或者,如果您只有一个用户帐户,则可以在屏幕会话中运行它。然后你甚至可以观察输出以进行错误诊断。

答案 5 :(得分:0)

这是我刚刚想到的并且运行良好,这是我的 php 脚本:

$start = time();
$now = time();
while (($now - $start) < 55) {
  echo "do some work";
  sleep(5); // if you want
  $now = time();
}

这里的想法是循环直到您已经运行了 55 秒。然后脚本将在下一分钟结束之前踢出,届时它会被 cron 再次触发。

睡眠是可选的,当然可以是您认为适合您工作的任何数量。

也可以将 55 秒值调整为小于 55,以确保您不会滚动到下一分钟,然后运行 ​​2 个版本。 (也可以使用锁来确保您不会同时运行 2 个副本,但这是一个不同的问题)

希望这对某人有所帮助..我知道这是一个老问题!