monit:检查没有pidfile的进程

我正在寻找一种方法来杀死已经运行超过X时间的给定名称的所有进程。 我产生了这个特定的可执行文件的许多实例,有时会进入一个糟糕的状态,并永远运行,占用大量的CPU。

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

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

你将如何在monit中expression这一点?

在monit中,您可以为没有PID的进程使用匹配的string。 使用名为“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 

也许如果你检查CPU负载是否在10个监控周期(每个30秒)处于一定的水平,那么重新启动或终止,这可能是一个选项。 或者,您可以对与进程相关的文件使用monit的时间戳testing 。

没有现成的工具使用该function。 假设您想要杀死比分钟更长的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将按名称select进程, ps -o pid,time为每个pid打印运行ps -o pid,time ,然后分析线路,从中提取时间,如果时间与定义的时间进行比较,则打印pid。 结果传给了杀。

我用ps-watcher解决了这个确切的问题,几年前在linux.com上写了这个问题。 ps-watcher确实允许你监视进程并根据累计的运行时间杀死它们。 以下是相关的ps-watcherconfiguration,假设你的进程名为'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-watcher是轻量级且易于安装的,所以除了monit安装之外,运行它并没有什么坏处。

Monit可以从版本5.4开始:

 if uptime > 3 days then restart 

请参阅: 项目CHANGES文件

你可以把它作为一个exec语句来处理。

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