我想知道是否有人可以指出我正确的方向。我对 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