Назад | Перейти на главную страницу

Используйте monit для мониторинга подпроцессов apache2

В настоящее время я использую Monit для мониторинга Apache и перезапускаю его, если использование памяти слишком велико. Однако я также хотел бы иметь возможность отслеживать отдельные порождаемые подпроцессы apache2 и убивать любой подпроцесс, использование памяти которого слишком велико, в течение нескольких минут. Как я могу это сделать?

Документация 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 вместо выхода.

Сценарии, конечно же, носят иллюстративный характер, и их следует модифицировать для вашей среды.

Я принял ответ 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

/ и т.д. / 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"
...