Cron 作业检查 PHP 脚本是否正在运行,如果没有则运行

Cron 作业检查 PHP 脚本是否正在运行,如果没有则运行

我想知道是否有人可以指出我正确的方向。我对 Linux 命令行的使用经验很少,最近由于工作中的各种因素,我需要学习一些知识。

基本上我有两个php脚本驻留在我的服务器上的目录中。为了应用程序的目的,这些脚本必须连续运行。目前我是这样实现的:

nohup sh -c 'while true; do php get_tweets.php; done' >/dev/null &

nohup sh -c 'while true; do php parse_tweets.php; done' >/dev/null &

然而,我注意到,尽管无限循环,脚本还是会定期停止,我被迫重新启动它们。我不知道为什么,但他们确实这么做了。这让我开始考虑一项工作的前景,CRON该工作检查它们是否正在运行,如果没有,则运行/重新启动它们。

有人可以向我提供一些有关如何进行此操作的信息吗?

答案1

我想扩展 Davidann 的答案,因为您对 cron 作业的概念不熟悉。每个 UNIX 或 Linux 系统都在某处存储有一个 crontab。 crontab 是一个纯文本文件。考虑以下几点:(从Gentoo Wiki 上的 Cron

#Mins  Hours  Days   Months  Day of the week
10     3      1      1       *       /bin/echo "I don't really like cron"
30     16     *      1,2     *       /bin/echo "I like cron a little"
*      *      *      1-12/2  *       /bin/echo "I really like cron"

这个 crontab 应该每隔一个月的每一天的每一小时的每一分钟都回显“我真的很喜欢 cron”。显然,只有当你真的喜欢 cron 时,你才会这样做。 crontab 还会在 1 月和 2 月每天 16:30 回显“我有点喜欢 cron”。它还会在 1 月 1 日 3:10 回应“我不太喜欢 cron”。

作为 cron 的新手,您可能想对加星号的列进行注释,以便了解每列的用途。我所知道的每个 Cron 实现都是这个顺序。现在将 Davidann 的答案与我评论的文件合并:

#Mins  Hours  Days   Months  Day of week
  *     *      *      *       *   lockfile -r 0 /tmp/the.lock && php parse_tweets.php; rm -f /tmp/the.lock
 

如果在每列中不输入任何值,则默认为:
整周每个月的每一天的每小时的每一分钟,--> 整年的每一分钟。

正如 Davidann 所说,使用锁定文件可确保仅运行 php 解释器的一个副本,这php parse_tweets.php是“运行”文件的命令,并且该行的最后一位将删除锁定文件,为下一次运行做好准备。我不喜欢每分钟删除一个文件,但如果这是您需要的行为,那么这是非常可以接受的。写入和重写到磁盘只是个人喜好

答案2

与其使用单独的 cron 在它没有运行时启动它,为什么不只使用 cron 呢?

例如:

* * * * * 'lockfile -r 0 /tmp/the.lock && (php parse_tweets.php; rm -f /tmp/the.lock)'

这将运行 cron 作业,该作业将parse_tweets.php使用锁定文件每分钟执行一次,这样您一次只能运行 cron 运行的一个副本。 (不过它不会阻止你php parse_tweets.php在 cron 之外运行)

答案3

定期检查既不方便也不可靠。如果您的脚本停止,它们将不会重新启动,直到 cron 作业再次运行。

确保进程始终运行的工具,例如supervise来自守护进程工具,监控,上帝,监督者等。开机时启动监控工具,不要管它。

while true; do … done是一个粗糙但有效的监控工具,但您需要采取一些预防措施。nohup是一个开始。确保重定向标准输入,使其不是终端(某些实现可以nohup为您做到这一点)。您应该将输出记录到文件中,并检查该文件以防出现错误。

nohup sh -c 'while true; do …; done' </dev/null >myscript.log 2>&1 &

还要确保您的 shell 在退出时不会向该作业发送信号。如果您的 shell 有disown内置命令,请运行它。

在许多系统上,您可以通过注册一个条目来安排 Supervisor 在引导时启动@reboot。检查crontab(5)您系统上的手册页以查看是否@reboot受支持。

@reboot while true; do …; done </dev/null >myscript.log 2>&1

相关内容