使用 monit 在知道它是 PID 的情况下杀死正确的进程

and*_*rej 3 monit

我正在尝试使用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,以便我可以杀死正确的进程。

and*_*rej 5

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)