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

Posted

技术标签:

【中文标题】如何每分钟更频繁地运行 Cronjobs?【英文标题】:How to run Cronjobs more often than once per minute? 【发布时间】:2011-06-08 00:39:21 【问题描述】:

我创建了一个电子邮件队列数据库表。我将把我的 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']);

【问题讨论】:

superuser.stackexchange.com 上可能有更多知识渊博的人。 你想要一个 php 守护进程,而不是一个 cron 脚本。 看看https://crontab.guru/,一个非常好的各种cron配置网站。 【参考方案1】:

这必须在脚本级别完成。

// 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】:

这是我编写的一个简单的 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

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

怎么样:

* * * * * 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

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:

这是我刚刚想到的并且运行良好,这是我的 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 个副本,但这是另一个问题)

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

【讨论】:

以上是关于如何每分钟更频繁地运行 Cronjobs?的主要内容,如果未能解决你的问题,请参考以下文章

Cron 作业——每 5 秒运行一次

类似优步的应用程序如何如此频繁地发布后台位置更新? [关闭]

如何使用 Django 运行自己的守护进程?

在Android 8中使用带DOZE的GPS

如何强制事件跟踪会话更频繁地刷新数据?

Cronjob 卡住而不退出