PHP:运行计划的作业(cron作业)

时间:2020-03-06 14:35:28  来源:igfitidea点击:

我的网络酒店上有一个网站,我想在上面运行一些预定的任务。我们会建议采用哪些方法实现这一目标?

到目前为止,我已经想到的是在每个页面的顶部都包含一个脚本,然后让该脚本检查是否需要运行该作业。

这只是我在想的一个简单示例:

if ($alreadyDone == 0 && time() > $timeToRunMaintainance) {
   runTask();
   $timeToRunMaintainance = time() + $interval;
}

我还有什么需要考虑的,或者有比这更好的方法了吗?

解决方案

这就是cronjobs的目的。 man crontab,假设我们正在运行Linux服务器。如果我们没有外壳访问权限或者无法设置cronjobs,则可以使用免费服务在外部服务器上设置cronjobs并pingURL之一。

如果我们想知道如何从cron实际运行PHP脚本,有两种选择:直接调用PHP解释器(即" php /foo/myscript.php"),或者使用lynx(lynx http:// mywebsite)。 com / myscript.php)。选择哪种脚本主要取决于脚本需要如何配置其环境,路径和文件访问权限会有所不同,具体取决于我们是通过Shell还是通过Web浏览器进行调用。我建议使用山猫。

副作用是我们每次运行时都会收到一封电子邮件。为了解决这个问题,如果我的cron PHP脚本成功完成,则不输出任何内容(并且必须不输出任何内容,甚至不包含空格),如果失败则返回错误消息。然后,我使用来自cron的小型PHP脚本来调用它们。这样,我只会收到一封失败的电子邮件。这与lynx方法基本相同,除了我的shell脚本发出HTTP请求而不是lynx。

将此脚本称为" docron"或者其他名称(记住chmod + x),然后在crontab中使用以下命令:" docron http://mydomain.com/myscript.php"。如果页面返回内容,它将通过电子邮件将页面输出作为HTML电子邮件发送给我们。

#!/usr/bin/php
<?php

$h = @file_get_contents($_SERVER['argv'][1]);

if ($h === false)
{
        $h = "<b>Failed to open file</b>: " . $_SERVER['argv'][1];
}

if ($h != '')
{
        @mail("[email protected]", $_SERVER['argv']['1'], $h, "From: [email protected]\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
}

?>

命令行PHP + cron将是我的选择。这很简单,应该符合要求。当然,它通常与PHP一起安装。

如果我们有cPanel主机,则可以通过Web界面添加cron作业。转到"高级"->" Cron作业",然后使用非高级格式设置cron频率。我们需要这样的命令:

/usr/bin/php /path/to/your/php/script.php

如果我们想避免设置cron作业之类的方法(尽管我建议这样做是更好的方法),那么我们提供的解决方案就很好。在许多项目中,我已经让PHP脚本本身进行了检查,以查看是否该运行更新。

不利的一面(好的,不利的一面)是,如果在一定时期内没有人使用该应用程序,则该脚本将无法运行。

有利的一面是,如果在一段时间内没有人使用该应用程序,则该脚本将无法运行。我设置的任务是诸如"更新缓存文件","进行每日备份"之类的事情。如果某人没有使用该应用程序,那么我们将不需要更新的缓存文件,也无需进行任何数据库更改即可备份。

我建议对方法进行的唯一修改是,仅当某人成功登录后才运行这些检查。我们无需在每次页面加载时都进行检查。

我现在正在回答这个问题,因为似乎没有人提到过这种确切的解决方案。

在我目前正在使用的网站上,我们使用cPanel设置了cron作业,而不是直接运行PHP Interpreter(因为我们使用的是CodeIgniter,并且我们的代码映射到了控制器函数,所以可能不是这样)一个好主意),我们正在使用wget

wget -q -O cron_job.log http://somehost/controller/method

-q是为了使wget不会生成任何输出(因此我们将不会继续收到电子邮件)。 -O cron_job.log会将控制器生成的所有内容保存到日志文件(每次都覆盖,因此不会持续增长)。

我发现这是使"适当的" cron工作的最简单方法。

Cron是用于调度问题的通用解决方案。但是,当计划大而频率高时,可能会出现可靠性/重叠问题。如果看到此类问题,请考虑进行监督或者更复杂的监控。