web-dev-qa-db-ja.com

monitを使用してApache2サブプロセスを監視します

現在、Monitを使用してApacheを監視し、メモリ使用量が多すぎる場合は再起動しています。ただし、生成された個々のApache2サブプロセスを監視し、メモリ使用量が数分間で高すぎるサブプロセスを強制終了できるようにもしたいと思います。どうやってやるの?

4
Matt White

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でキルが行われます。

もちろん、スクリプトは説明のためのものであり、環境に合わせて変更する必要があります。

3
cjc

上記の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"
...
2
Matt White