В настоящее время я использую 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"
...