我正在尝试使用监控找到运行时间过长的潜在进程并将其终止。
机器正在运行并行构建,因此有可能同时运行多个 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 的逻辑。