Crontab - 如何以正确的方式做到这一点?

时间:2012-02-21 20:42:27

标签: php cron

应用程序的一个非常常见的需求是每X分钟/小时运行一个脚本。基本上它没什么复杂的,只是一些PHP代码和一个crontab条目。

虽然过去几年我写了很多这些cronjobs但我还没有看到任何最佳实践,至少没有那么多。与每次“后台处理”一样,许多事情都可能出错,尤其是在生产环境中。

其中:

  • 执行cron期间发生错误,脚本处理了一半数据
  • cronjob意外地由另一个进程/用户错误/无论
  • 启动两次
  • cronjob比预期更长的时间并且脚本再次被调用,尽管它没有完成处理数据

编写坚如磐石,强大的cronjob脚本有哪些最佳实践?编写一个锁定文件,断言只有一个实例运行,在oder中进行大量的日志记录和监控,以防止发送数千个重复的电子邮件?你有什么想法?

2 个答案:

答案 0 :(得分:2)

就个人而言,我处理错误的方法是简单地将STDERR发送到日志文件,然后定期检查该文件。一种简单的方法是将2> / pathtolog附加到crontab条目。

至于运行相同程序的重复项,我更喜欢让脚本尝试锁定某些内容(文件或本地网络端口)。如果它无法获得该锁定,则脚本不会运行。这样,如果现有脚本当前正在运行,则新脚本无法获得相同的锁。

答案 1 :(得分:0)

你可以做很多事情。

根据您的需要,将您的cron脚本/二进制文件(我猜是因为您提到它们是用PHP编写的)设置为可由所有者或组执行。

如果您想确保它们仅由cron执行,那么请创建一个cron用户,该用户是唯一可以执行该脚本的用户。然后将该用户设置为在crontab条目中运行它。

在你的cron脚本中输出它所做的重要事情。在输出前加上时间戳/日期戳(取决于它运行的频率)。这样可以轻松地在日志文件中的特定时间进行grep。

通过将>> /path/cron.log添加到crontab条目,将脚本的stdout附加到日志文件中。

您还可以输出cronjob的开始时间和结束时间,以便您可以每隔一段时间分析一次日志,以确保过程不会太慢。

您的日志文件可能如下所示:

[ Tue Feb 20, 2012 ]:
[ Tue Feb 20, 2012 ]: Executing mycron.php
[ Tue Feb 20, 2012 ]: 
[ Tue Feb 20, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`""
[ Tue Feb 20, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 12324123)
[ Tue Feb 20, 2012 ]: 
[ Tue Feb 20, 2012 ]: Finished executing mycron.php. Time taken: 3.462 seconds
[ Tue Feb 21, 2012 ]:
[ Tue Feb 21, 2012 ]: Executing mycron.php
[ Tue Feb 21, 2012 ]: 
[ Tue Feb 21, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`""
[ Tue Feb 21, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 10376123)
[ Tue Feb 21, 2012 ]: 
[ Tue Feb 21, 2012 ]: Finished executing mycron.php. Time taken: 2.998 seconds

除了做任何事情,而不是那两个随机查询,当然。