监控“检查程序”并根据退出代码重新启动

监控“检查程序”并根据退出代码重新启动

当我使用时check process,monit 将启动我定义的程序,start program然后如果它停止,monit 将重新启动它。

但是当我使用check programmonit 时它不会自动启动。如果程序正在运行,并且由于某种原因它以非 0 的退出代码停止,monit 将不会重新启动它(请参阅下面的配置)。

我真的不确定如何根据我的退出代码正确启动和重新启动该程序。

我的配置文件如下所示:

set logfile /tmp/monit.log

set daemon  1
check program MyProgram with path “/monit/MyProgram.py”
        and with timeout 3600 seconds 
    every 1 cycles
    start program = “/monit/MyProgram.py” with timeout 3600 seconds
    if status > 200 then restart
    if status < 201 then stop
    if 2 restart 5 cycles then exec “/monit/custom_script.sh”
    if 2 restart 5 cycles then stop

我尝试过像这样启动monit:

  • monit -c monitrc -vv
  • monit -c monitrc start all -vv
  • monit -c monitrc start MyProgram -vv

答案1

(提前抱歉回答得太长^^)

把事情做好

但是当我使用check programMonit 时它不会自动启动。如果程序正在运行,并且由于某种原因它以非 0 的退出代码停止,monit 将不会重新启动它(请参阅下面的配置)。

Monit 中的aprocess和 a有显著的区别:program

一个过程是在后台运行的二进制文件 - 守护进程(如 HTTPd、DB 服务器等)。Monit 不运行进程。Monit 并不真正控制这些应用程序。但是,它可以与守护进程交互。例如:systemctl start nginx不会在前台运行 nginx(并阻止您的 bash),但会在后台启动守护进程(即使您终止会话后,它仍会继续运行)。

一个程序是由 Monit 执行和控制的二进制文件。此程序应在一段时间后退出,Monit 将对所有情况做出反应。例如:du -hd1将运行、创建输出并退出。然后,您可以根据状态代码、内容等对执行结果/输出做出反应。


配置注意事项

您正在尝试使用check program来守护您的应用程序。据我所知,这不会起作用。我认为check process在这种情况下您需要这样做。您需要守护进程为此设置你的脚本。稍后再讨论这个问题...

    if status > 200 then restart
    if status < 201 then stop

如果发生异常情况,Monit 会进行交互。此配置告诉 Monit:

  • 如果发生以下情况,则会发生不寻常的事情status > 200
  • 如果发生以下情况,则会发生不寻常的事情status < 201

这就导致了成功状态一切都很好。你会让自己处于警觉状态 ;)

    if 2 restart 5 cycles then exec “/monit/custom_script.sh”
    if 2 restart 5 cycles then stop

这是对同一事件做出反应的两个操作。它应该停止并运行脚本。这可能会起作用,但理解起来有点奇怪……


结果 - 有点

解决这个问题的最佳方法是从你的 python 脚本中获取一个 pidfile。由于我对 python 一无所知,所以这取决于你 ;-)

为自己创建 pidfile 的一个非常肮脏的方法是使用 bash 脚本(/monit/MyProgram-daemonize):

#!/usr/bin/env bash
(
    /monit/MyProgram.py &
    echo -n "$!" > "/tmp/MyProgram.pid"
) &

还有一个(/monit/MyProgram-kill):

#!/usr/bin/env bash

if [[ -f /tmp/MyProgram.pid ]]; then
    kill -SIGTERM $(cat /tmp/MyProgram.pid)
    wait $(cat /tmp/MyProgram.pid)
    rm -f /tmp/MyProgram.pid
    exit 0
fi

exit 1

评论:

  • /tmp/由于/run权限原因我使用了
  • 我使用了kill -SIGTERM,因为kill -SIGKILLkill -9都是邪恶的;)您可能需要调整这个……

check process然后你可以使用:

check process MyProgram pidfile "/tmp/MyProgram.pid"
  start program = "/monit/MyProgram-daemonize" as uid myNonRootUserHere
  stop program = "/monit/MyProgram-kill" as uid MyNonRootUserHere

  if failed then restart
  if 3 restarts within 5 cycles then unmonitor

这种方法的最大缺陷是可能重复使用 pid。Monit 在 pid 文件和二进制文件之间没有任何联系。因此,如果您的 python 从 pid 100 开始并被终止,但另一个进程占用了 pid 100,您的 Monit 将不会注意到它并认为一切正常。因此,您应该添加一个检查(当然是示例;如果您的程序不提供 HTTPd,那么该检查可能不是下一个最佳选择):

  if failed uid MyNonRootUserHere then restart

  if failed
    host 127.0.0.1
    port 80
    protocol http
    request "/"
  then alert

相关内容