如何使Cronjobs每分钟运行一次以上?

15

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

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

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

我目前的解决方法是使用一个额外的睡眠参数来调用脚本,并复制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']);

1
在superuser.stackexchange.com上可能有更有经验的人。 - EboMike
2
你需要一个 PHP 守护进程,而不是一个 cron 脚本。 - user557846
请查看https://crontab.guru/,这是一个非常好的用于各种cron配置的网站。 - Mark
6个回答

16

这必须在脚本层面完成。

// 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
}

15

这是我写的一个简单的bash脚本,可以与crontab结合使用以便更频繁地运行。

您可以将其保存为~/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

11

首先,我建议使用PHP的命令行版本而不是使用curl调用脚本。这样,您可以创建一个PHP脚本,并设置合理的生命周期,不必在规定的时间内输出响应。

因此,您可以在PHP脚本中简单地sleep/check for emails/transmit/sleep等操作,而无需不必要地使用cron。

另外,我建议注意确保多个PHP脚本不同时操作数据库表,可以通过使用pid文件或数据库设置方法(如果存在/已设置给定的文件/设置,则中止处理),或通过合理计时cron作业并通过检查脚本运行时间来限制脚本的最大处理时间,然后开始“检查邮件”部分的周期。


2
如果您每10秒钟执行一次,那么cron并不是完成此任务的正确工具。您需要一个像Ish展示的连续运行的脚本。
您可以将脚本注册为服务,方法是将相应的启动/停止脚本放入/etc/init.d中并启用它。
或者,如果您只有用户帐户,则可以在屏幕会话中运行它。然后您甚至可以观察输出以进行错误诊断。

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

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个副本同时运行,但这是另一个问题)

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接