我目前正在使用 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"
...