我正在尝试使用monit来查找运行时间过长的surefire进程并杀死它们。
机器正在运行并行构建,因此可以同时运行多个万无一失的进程,但这些进程没有 PID 文件。
我的 monit 配置如下所示:
check process surefire matching "surefire/surefirebooter"
if uptime > 4 hours then alert
if uptime > 4 hours then stop
Run Code Online (Sandbox Code Playgroud)
警报已发送,但停止不起作用。
我无法使用killall,因为该进程由 java 运行,并且还有其他几个 java 进程正在运行。
我所需要的只是检测该进程的正确 PID,以便我可以杀死正确的进程。
有MONIT_PROCESS_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
Run Code Online (Sandbox Code Playgroud)
唯一的问题是 monit 无论如何都不是这项工作的正确工具,因为它希望每次执行检查时都能找到与检查模式匹配的进程,否则它会尝试使用检查定义的开始部分(这是不完全是我们想要做的)。
所以我找到并修改了我通过 cron 运行的这个 ps/grep/perl/xargs oneliner。它能够通过它的命令行子字符串查找进程,选择长时间运行的进程并妥善对待它们。
#!/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
Run Code Online (Sandbox Code Playgroud)