使用monit监控apache2子进程

使用monit监控apache2子进程

我目前正在使用 Monit 来监控 Apache,如果其内存使用率过高,则重新启动它。但是,我还希望能够监控生成的单个 apache2 子进程,并在几分钟内终止任何内存使用率过高的子进程。我该怎么做?

答案1

Monit 的文档表明您可以本地监控 Apahce 及其子进程使用的总内存,而不是任何单个子进程。

但是,您可以使用测试检查脚本的返回状态check program

http://mmonit.com/monit/documentation/monit.html#program_status_testing

因此,你可以执行如下检查脚本:

#/bin/bash
threshold=10000 # 10MB

for childmem in $(ps h orss p $(pgrep -P $(cat /var/run/httpd.pid)))
do
  if [ $childmem -gt $threshold ]; then
     exit 1
  fi
done
exit 0

如果该脚本是/usr/local/bin/check_apache_children.sh,那么您可以执行以下操作:

 check program myscript with path "/usr/local/bin/check_apache_children.sh"
       if status != 0 then exec "/usr/local/bin/kill_apache_children.sh"

终止脚本大概看起来像检查脚本,但是会终止 PID 而不是退出。

当然,这些脚本只是说明性的,应该根据您的环境进行修改。

答案2

我接受了 cjc 的上述回答,但想发布我如何使用他的建议来解决这个问题。请注意,您需要至少使用 Monit 5.3 才能使用 Monit 的“检查程序”。我正在运行 Debian。

在 /usr/local/bin/monit_check_apache2_children中:

#!/usr/bin/env bash

log_file=/path/to/monit_check_apache2_children.log
mem_limit=6
kill_after_minutes=5

exit_code=0
date_nice=$(date +'%Y-%m-%d %H:%M:%S')
date_seconds=$(date +'%s')
apache_children=$(ps h -o pid,%mem p $(pgrep -P $(cat /var/run/apache2.pid)) | sed 's/^ *//' | tr ' ' ',' | sed 's/,,/,/g')

for apache_child in $apache_children; do
  pid=`echo $apache_child | awk -F, '{ print $1 }'`
  mem=`echo $apache_child | awk -F, '{ print $2 }'`
  mem_rounded=`echo $apache_child | awk -F, '{ printf("%d\n", $2 + 0.5) }'`

  if [ $mem_rounded -ge $mem_limit ]; then
    log_entry_count=$(cat $log_file | grep -v 'KILLED' | grep " $pid; " | wc -l)
    log_entry_time=$(cat $log_file | grep -v 'KILLED' | grep " $pid; " | tail -$kill_after_minutes | head -1 | awk '{ print $3 }')

    if [ "$1" != "kill" ]; then
      echo "$date_nice $date_seconds Process: $pid; Memory Usage: $mem" >> $log_file
    fi

    if [ $((date_seconds - log_entry_time)) -le $(((kill_after_minutes * 60) + 30)) ] && [ $log_entry_count -ge $kill_after_minutes ]; then
      if [ "$1" = "kill" ]; then
        kill -9 $pid
        echo "$date_nice $date_seconds ***** KILLED APACHE2 PROCESS: $pid; MEMORY USAGE: $mem" >> $log_file
      else
        exit_code=1
      fi
    fi
  fi
done

exit $exit_code

在/etc/monitrc中:

...
check program apache2_children
  with path "/usr/local/bin/monit_check_apache2_children"
  if status != 0 then exec "/usr/local/bin/monit_check_apache2_children kill"
...

相关内容