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

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

2 ответа

Решение

Документация Monit предполагает, что вы можете контролировать общий объем памяти, используемой Apahce и его дочерними процессами, а не какой-либо отдельный дочерний процесс.

Однако вы можете проверить статус возврата скрипта, используя check program тестовое задание:

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

Итак, вы можете сделать что-то вроде этого в качестве сценария проверки:

#/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 / местные / бен / 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"
...
Другие вопросы по тегам