设置 cron 作业以检查长时间运行的进程是否仍在进行(如果没有,则启动它)的最佳方法是什么?

设置 cron 作业以检查长时间运行的进程是否仍在进行(如果没有,则启动它)的最佳方法是什么?

根据标题:

设置 cron 作业以检查长时间运行的进程是否仍在进行(如果没有,则启动它)的最佳方法是什么?

如果我在 cron 中启动一个长时间运行的进程,它会被阻塞吗?或者 cron 会将该进程分叉为一个独立的子进程?

谢谢!

答案1

设置 cron 作业以检查长时间运行的进程是否仍在进行(如果没有,则启动它)的最佳方法是什么?

一个简单的方法是使用一个简单的脚本来检查进程是否正在运行,然后在必要时重新启动它。

(有时最好通过“虚拟事务”来实际验证进程是否正在运行,例如,为了验证 SMTP 进程,您可以建立 TCP 端口连接并检查其是否正确响应。)

但是一定要注意您作为交互式用户时以及当 cron(8) 运行您的脚本时的环境之间的差异。

回答问题的第二部分:

如果我在 cron 中启动一个长时间运行的进程,它会被阻塞吗?或者 cron 会将该进程分叉为一个独立的子进程?

cron(8) 将分叉执行一个 cron 作业,但除非你的脚本或进程“分离”,否则 cron 将把它作为子进程维持直到它退出(这就是 cron 能够从 stderr 收集所有输出并通过电子邮件发送的方式。)

但是,我想你会想,你真的可以从 cron 运行长时间运行的进程吗?如果你这样做,你需要确保它只能启动自身的一个副本,并且如果它已经在运行,它将快速退出。

让长时间运行的进程保持运行的更好的解决方案——如果你只担心退出或崩溃

  • 如果可以让进程保持连接,请通过 inittab(5) 和 'respawn' 选项使用 init(1)。通常,守护进程也具有“无 fork”选项。
  • 或者,如果你的操作系统没有 inittab 功能,或者你无法访问它,请使用类似 DJB 的守护进程工具
  • 如果您有幸使用 Solaris 10 或 OpenSolaris,则可以使用 SMF。(这甚至可以与执行 fork 和 detach 的进程一起工作。)
  • 如果这是您自己的代码,您可以编写它以具有一对父/子进程,其中父进程在收到 SIGCHLD 时重新启动子进程。

答案2

一个常见的习惯做法是,长时间运行的进程会有一个 pid 文件。基本上就是一个文件/var/run或类似文件,其中只包含程序的 pid 或进程 ID。程序启动时会将文件放在那里,程序停止时会删除该文件。您可以通过查看该文件是否存在来轻松检查程序是否存在。

这也可用于查看程序是否已崩溃。如果文件存在,但没有使用该 pid 运行的进程,则程序已停止,但未删除 pid 文件,即程序已崩溃。在这种情况下,您可以删除 pid 文件并重新启动程序。然而,这并不是万无一失的,因为有时 PID 可能会被原始进程崩溃后启动的新进程重用。

答案3

根据你如何检测你的进程,cronjob 可能看起来像

* * * * * pidof 可执行文件 || /usr/local/bin/executable

前提是您的可执行文件在进程列表中显示为自身。更明智的方法是使用 pidfile 并使用 start-stop-daemon。实际上,这完全取决于所讨论的进程。不久前,我还编写了一个小型进程维护守护进程杜德基正是为了这个目的。

并且,cron 不会阻止,但是根据您进程的性质,您可能还是希望将其置于后台。

答案4

监控旨在解决这个问题。

相关内容