現在、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の「チェックプログラム」を使用するには、少なくともMonit5.3を使用する必要があることに注意してください。私は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"
...