monit:检查没有 pidfile 的进程

monit:检查没有 pidfile 的进程

我正在寻找一种方法来终止所有具有给定名称且运行时间超过 X 的进程。我生成了这个特定可执行文件的多个实例,有时它会进入不良状态并永远运行,占用大量 CPU。

我已经在使用 monit,但我不知道如何在没有 pid 文件的情况下检查进程。规则如下:

kill all processes named xxxx that have a running time greater than 2 minutes

您将如何在 monit 中表达这一点?

答案1

在 monit 中,您可以对没有 PID 的进程使用匹配字符串。以名为“myprocessname”的进程为例,

check process myprocessname
        matching "myprocessname"
        start program = "/etc/init.d/myproccessname start"
        stop program = "/usr/bin/killall myprocessname"
        if cpu usage > 95% for 10 cycles then restart

也许,如果你检查 10 个监控周期(每个 30 秒)内的 CPU 负载是否处于某个水平,然后重新启动或终止,这可能是一个选择。或者你可以使用monit 的时间戳测试与该流程相关的文件。

答案2

目前还没有现成的工具具备该功能。假设您想要终止运行时间超过 1 分钟的 php-cgi 脚本。请执行以下操作:

pgrep php-cgi | xargs ps -o pid,time | perl -ne 'print "$1 " if /^\s*([0-9]+) ([0-9]+:[0-9]+:[0-9]+)/ && $2 gt "00:01:00"' | xargs kill

pgrep将按名称选择进程,ps -o pid,time打印每个 pid 的运行时间,然后分析行,从中提取时间,如果时间与定义的时间比较则打印 pid。结果传递给 kill。

答案3

我使用 ps-watcher 解决了这个问题,并写了这篇文章linux.com几年前。ps-watcher 确实允许您监视进程并根据累计运行时间终止它们。以下是相关的 ps-watcher 配置,假设您的进程名为“foo”:

[foo]
  occurs = every
  trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1
  action = <<EOT
  echo "$command accumulated too much CPU time" | /bin/mail user\@host
  kill -TERM $pid
EOT

[foo?]
   occurs = none
   action = /usr/local/etc/foo restart

关键是那条线

trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1`

意思是‘如果累计处理时间 > 1 小时并且我不是父进程,请重新启动我。

因此,我意识到答案没有使用 monit,但它确实有效。 ps-观察者重量轻并且易于设置,因此在 monit 设置之外运行它没有任何坏处。

答案4

您可以将其作为 exec 语句放入 monit 中。

    if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi

相关内容