使用 monit 来终止正确的进程,而无需知道它的 PID

使用 monit 来终止正确的进程,而无需知道它的 PID

我正在尝试使用监控找到运行时间过长的潜在进程并将其终止。

机器正在运行并行构建,因此有可能同时运行多个 surefire 进程,但这些进程没有 PID 文件。

我的监控配置如下:

check process surefire matching "surefire/surefirebooter"
    if uptime > 4 hours then alert
    if uptime > 4 hours then stop

警报已发送,但停止不起作用。

我不能使用全杀因为该进程由 java 运行,并且还有几个其他 java 进程正在运行。

我所需要的只是检测该进程的正确 PID,这样我就可以正确的那一个。

答案1

监控进程的PID环境变量传播到 exec 命令执行的程序的上下文中。

if uptime > 4 hours then stop

应该被替换为

if uptime > 4 hours then exec "/usr/bin/monit-kill-process.sh"

并且 /usr/bin/monit-kill-process.sh 应该看起来像

#!/bin/bash
# script run from monit instance
# this will find long-running surefire process and kill it

kill -9 $MONIT_PROCESS_PID

唯一的问题是,monit 无论如何都不是适合这项工作的工具,因为它希望进程与查看每次执行检查时都要找到模式,否则它会尝试使用开始检查定义的一部分(这不是我们想要做的)。

所以我成立并修改了我通过 cron 运行的这个 ps/grep/perl/xargs 单行程序。它能够通过命令行子字符串找到进程,选择长时间运行的进程并妥善处理它们。

#!/bin/bash
# script run from monit instance
# this will find long-running surefire process and kill it

readonly PROCESS_STRING="surefireboot"

/bin/ps -e -o pid,time,command \
 | /bin/grep $PROCESS_STRING \
 | /usr/bin/perl -ne 'print "$1 " if /^\s*([0-9]+) ([-0-9]+:[0-9]+:[0-9]+)/ && $2 gt "04:00:00"' \
 | /usr/bin/xargs kill

答案2

Monit 可能不是适合此目的的工具。模式匹配仅使用第一个匹配。

可以使用以下方法进行测试monit procmatch <pattern>

我建议用唯一的标识符标记您的构建并在模式匹配序列中使用它...或者完全用 monit 管理守护进程。

您也不需要使用 killall。也许可以使用一些围绕 pkill 或 pgrep 的逻辑。

另请参阅:monit:检查没有 pidfile 的进程

相关内容