PHP:运行计划作业(cron 作业)
Posted
技术标签:
【中文标题】PHP:运行计划作业(cron 作业)【英文标题】:PHP: running scheduled jobs (cron jobs) 【发布时间】:2010-09-12 07:46:11 【问题描述】:我的 webhotel 上有一个网站,我想在其上运行一些计划任务。您会推荐什么方法来实现这一目标?
到目前为止,我的想法是在每个页面的顶部包含一个脚本,然后让该脚本检查是否该运行此作业。
这只是我正在考虑的一个简单示例:
if ($alreadyDone == 0 && time() > $timeToRunMaintainance)
runTask();
$timeToRunMaintainance = time() + $interval;
还有什么我应该考虑的,或者有比这更好的方法吗?
【问题讨论】:
【参考方案1】:这就是 cronjobs 的用途。 man crontab
假设您正在运行 linux 服务器。如果您没有 shell 访问权限或无法设置 cronjobs,可以使用免费服务在外部服务器上设置 cronjobs 并 ping 您的某个 URL。
【讨论】:
你知道可以推荐的人吗? siteuptime.com 可以设置为定期 ping 您网站上的页面 - 表面上检查正常运行时间,但如果它们位于可访问的脚本中,则可能会触发您的工作。最好的方法是设置您自己的 crontab/计划任务,因此意外的用户访问无法重新运行您的作业【参考方案2】:我现在回答这个问题,因为似乎没有人提到过这个确切的解决方案。
在我目前正在开发的网站上,我们使用 cPanel 设置了一个 cron 作业,但不是直接运行 php 解释器(因为我们使用的是 CodeIgniter 并且我们的代码被映射到一个控制器函数,这可能不是一个好主意)我们正在使用wget
。
wget -q -O cron_job.log http://somehost/controller/method
-q
是这样 wget 不会产生任何输出(所以你不会不断收到电子邮件)。 -O cron_job.log
会将控制器生成的任何内容保存到日志文件中(每次都会被覆盖,因此它不会继续增长)。
我发现这是让 cron 正常工作的最简单方法。
【讨论】:
谢谢,我喜欢 -q 开关,因为我一直在考虑如何阻止这些电子邮件的到来。你也很高兴分享你的建议:) -o location.log(小写o而不是大写o),可用于输出日志(当-q未设置时,通常会在stdout上输出)。 -a 与 -o 的作用相同,但附加到文件中,其中 -o 覆盖。【参考方案3】:如果您有 cPanel 主机,您可以通过 Web 界面添加 cron 作业。进入 Advanced -> Cron Jobs 并使用非高级表单设置 cron 频率。你想要这样的命令:
/usr/bin/php /path/to/your/php/script.php
【讨论】:
太好了,我正在寻找这个我认为 perl 我应该使用 /usr/bin/perl :p【参考方案4】:你看过ATrigger吗? PHP library 也可用于开始创建计划任务而无需任何开销。
免责声明:我是他们团队中的一员。
【讨论】:
您可能需要更新该链接,因为它将用户发送到http
协议而不是https
【参考方案5】:
如果您想知道如何从 cron 实际运行 PHP 脚本,有两种选择:直接调用 PHP 解释器(即“php /foo/myscript.php”),或使用 lynx(lynx http://mywebsite.com/myscript.php )。您选择哪一个主要取决于您的脚本需要如何配置其环境 - 路径和文件访问权限会有所不同,具体取决于您是通过 shell 还是 Web 浏览器调用它。我建议使用 lynx。
一个副作用是每次运行时您都会收到一封电子邮件。为了解决这个问题,如果它们成功完成,我让我的 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("cron@mydomain.com", $_SERVER['argv']['1'], $h, "From: cron@mydomain.com\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
?>
【讨论】:
我完全同意这里的意图。如果您不能直接调用解释器,另一个不错的选择是 wget。【参考方案6】:如果您想避免设置 cron 作业等(尽管我建议这是一种更好的方法),您提供的解决方案非常好。在许多项目中,我已经让 PHP 脚本本身进行检查以查看是否该运行更新了。
不利的一面(好吧,一个的不利方面)是如果在一段时间内没有人使用该应用程序,那么脚本将不会运行。
好处是,如果在特定时间段内没有人使用该应用程序,那么脚本将不会运行。我设置它要做的任务是“更新缓存文件”、“每日备份”等等。如果有人不使用该应用程序,那么您将不需要更新缓存文件,也不需要对备份进行任何数据库更改。
我建议对您的方法进行的唯一修改是,您只在有人成功登录时才运行这些检查。您不需要检查每个页面加载。
【讨论】:
【参考方案7】:Cron 是用于调度问题的通用解决方案。但是当你做大并且日程安排频率很高时,可能会出现可靠性/重叠问题。如果您发现此类问题,请考虑类似supervise 或更复杂的monit。
【讨论】:
对于存在重叠问题的高频任务,您将如何使用monit
?
由于存在 PID 文件锁定,您可以将其配置为仅运行文件的一个实例。但是,是的,使用 Solo 之类的工具,可以使用 Cron timkay.com/solo 实现类似的功能【参考方案8】:
如果你使用 cpanel,你应该像这样添加:
/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php
【讨论】:
【参考方案9】:我会使用 www.guardiano.pm 外包 cronjobs,并每 X 分钟调用一次 url。当您的网址(即 www.yoursite.com/dothis.php)被调用时,您将执行一些代码。如果你不想让网页在你想要的时候请求页面,你可以只允许在 POST 中请求并发送一些只有你知道的参数,使用 Guardiano.pm
这就是我会做的,因为我在我的宠物项目中这样做。玩得开心!
【讨论】:
【参考方案10】:如果您不想使用 cronjobs 或任何外部的东西,您使用的方法很好,但是每次加载页面时检查这些可能很繁重。
起初,一些 cronjobs 可能会被替换。例如,如果您有一个计数器来记录有多少用户在您的网站上注册,您可以在用户注册时简单地更新这个数字,这样您就不必为此使用 cronjob 或任何计划任务。
如果你想使用定时任务,我建议你使用你现在正在使用的方法,但是稍微修改一下。如果您的网站一天有足够的点击量,您可以简单地让任务运行(或任务检查功能运行)仅 1% 或 0.01% 的点击量而不是全部,您应该使用的百分比取决于在您拥有的页面点击次数以及您想要运行任务的次数。因此,只需添加一个随机化器即可实现此功能。
你可以简单地使用这样的函数;
if(rand (1, 100) <= 1) // 1, 100 is used to generate a number between 1 and 100. 1 is for one percent.
// Run the tasks system
【讨论】:
【参考方案11】:命令行 PHP + cron 将是我要走的路。这很简单,应该符合要求。它通常与 PHP 一起安装是理所当然的。
【讨论】:
【参考方案12】:如果您没有设置 cronjob 的选项,您可以使用 cUrl 调用脚本(作为 wget 的替代 - 相同的功能)。只需在执行 cUrl 功能的本地计算机上执行计划任务即可。
【讨论】:
问题是在将近 4 年前发布的,因此可以放心地假设这不再是问题。 :) 我通过谷歌找到了这个问题。其他人也在谷歌。 @Damiqib,我认为这个问题永远不会太老。将会有更新更好的方法来解决问题。所以我欢迎这个答案,即使它是一个老问题。【参考方案13】:如果您想要更抽象的东西,您可以考虑使用 PHP 调度程序之类的东西。 例如:
https://github.com/lavary/crunz https://github.com/peppeocchi/php-cron-scheduler此外,要解析 cron 表达式,您可以使用现有的库,例如 https://github.com/mtdowling/cron-expression。它提供了许多有用的方法来帮助您找出 cron 作业的信息。
希望对您有所帮助。
【讨论】:
以上是关于PHP:运行计划作业(cron 作业)的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 sidekiq 计划的 cron 作业没有在 heroku 上运行?