- 追加された行はこの色です。
- 削除された行はこの色です。
- サーバ外部監視 へ行く。
* [[サービス監視]] - 外部監視 [#fcc00e43]
外部監視は「WEBアプリとして外部から利用可能か」を監視するので、監視処理自体は象サーバのあるネットワーク外に設置する。~
外部監視は「WEBアプリとして外部から利用可能か」を監視するので、監視処理自体は対象サーバのあるネットワーク外に設置する。~
※監視処理への応答用の処理は対象サーバに設置しておく。~
※httpリクエストの結果からサーバ状態を判断するので余計なポートを空けたりしなくてもよい。~
#html(<table><tr><td colspan="2" style="font-size:100%;"> (1) 外部の監視処理からアクセスがあったときに状態を通知する下記のような処理を監視対象サーバに作成し、WEB公開ディレクトリに設置する。</td></tr><tr><td style="font-size:100%;">)
<?php
// 状態初期化
$web_status = "OK";
$db_status = "OK";
$mail_status = "OK";
// DB稼動チェック
$DAO = new Dao("oracle");
$DAO->err_log = "/var/log_db/status_chk_err.log";
$DAO->log_write = TRUE;
$DAO->connect(DB_NAME,DB_USER,DB_PASS);
$res = $DAO->s_query("select 'OK' STATUS from dual");
if ($res["tbl"][0]["STATUS"]!="OK"){ $db_status = "NG";}
$DAO->close();
$DAO = NULL;
// SMTPサーバ稼動チェック
$cmd = 'ps -A | grep sendmail | wc -l | awk \'{print $1;}\'';
$cnt = exec($cmd);
if ($cnt==0){
$mail_status = "NG";
}
// 状態表示
echo "{$web_status} {$db_status} {$mail_status}";
?>
#html(</td><td valign="top" style="font-size:100%;">)
[処理内容の補足]~
・ここではPHPにしたが稼動しているべきアプリの言語で&br;
書くのがよいと思う。&br;
・SSLやBASIC認証と組み合わせて&br;
一般ユーザからのアクセスを拒否したほうがよい。&br;
・DBにアクセスするアプリならDB接続を&br;
メール送信するアプリならメールサーバの稼動確認を行う。&br;
・PHPのセーフモードがOnの場合はexecはダメだった気がする。&br;
※DB周りは自前のクラスライブラリを利用。
#html(</td></tr></table>)
#html(<table><tr><td colspan="2" style="font-size:100%;"> (2) 以下のようなスクリプトを対象サーバのネットワーク外にあるマシンに作成する</td></tr><tr><td style="font-size:100%;">)
#!/bin/bash
#
# chkconfig: 345 99 01
# description: Process Check
# processname: chk_app
#
### 設定 START ##############################
# ステータス一時保存ファイル
status_txt="/tmp/svr_status.txt"
# このシェルの名前
own_name=`basename ${0}`
# 監視先サーバ名
server_name="www.example-server.com"
# 状態取得用URL
chk_url="http://${server_name}/xxxxxxx/xxxxx.php"
# チェック間隔(秒)
chk_range=600
# エラー時報告先ユーザ
email_to_file="/xxxx/xxxx/ADMIN_MAIL"
# 送信者
email_from="svr-chk@example.com"
# メール件名
subject="サーバ(${server_name})外部監視"
# メール送信用プログラム
sendmail="/usr/sbin/sendmail"
### 設定 END ################################
### 関数定義 START ##########################
## HELP表示
disp_help(){
echo "
使用法: `basename ${0}` start|stop
プロセス監視を開始/終了する
※サーバの状態を外部監視します
"
}
## 報告メール送信
report_mail(){
email_to=`cat $email_to_file`
mail_body=`echo "$1" | nkf -s`
subject=`echo "$subject" | nkf -j`
$sendmail -t <<_EOMAIL_
To: $email_to
From: $email_from
Subject: $subject
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="iso-2022-jp
$mail_body
.
_EOMAIL_
}
## 重複起動の回避処理
kill_prc(){
all_prc=`ps -A -l`
while [ $# -gt 0 ]
do
all_prc=`ps -A -l | grep $1`
chk_prc="$1
$all_prc"
kill_prc=`echo "$chk_prc" | awk '{
if(NR==1){
pid=$1;
} else {
if ($4==pid){
print $4" ";
}
if ($5==pid){
print $4" ";
}
}
}'`
kill -9 $kill_prc >/dev/null 2>&1
shift
done
}
## サーバチェックメイン処理
chk_app_main(){
CR='
'
## 状態の初期化
touch $status_txt
pre_status=`cat $status_txt`
if [ "$pre_status" == "" ];then
pre_status="INIT INIT INIT"
fi
pre_web_server=`echo "$pre_status" | awk '{print $1;}'`
pre_db_server=`echo "$pre_status" | awk '{print $2;}'`
pre_ml_server=`echo "$pre_status" | awk '{print $3;}'`
while [ ture ]
do
wget -O $status_txt $chk_url >/dev/null 2>&1
status=`cat $status_txt`
if [ "$pre_status" != "$status" ]; then
msg1=""
msg2=""
msg3=""
ml_status="停止"
db_status="停止"
web_status="停止"
web_server=`echo "$status" | awk '{print $1;}'`
db_server=`echo "$status" | awk '{print $2;}'`
ml_server=`echo "$status" | awk '{print $3;}'`
if [ "$web_server" != "$pre_web_server" ]; then
if [ "$web_server" == "OK" ]; then
web_status="起動"
fi
msg1="WEBサーバが${web_status}しました${CR}"
fi
if [ "$web_server" == "OK" ]; then
if [ "$db_server" != "$pre_db_server" ]; then
if [ "$db_server" == "OK" ]; then
db_status="起動"
fi
msg2="DB(Oracle)サーバが${db_status}しました${CR}"
fi
if [ $ml_server != "$pre_ml_server" ]; then
if [ "$ml_server" == "OK" ]; then
ml_status="起動"
fi
msg3="メール(SMTP)サーバが${ml_status}しました${CR}"
fi
fi
msg="${msg1}${msg2}${msg3}"
report_mail "$msg"
fi
#
pre_status="$status"
pre_web_server="$web_server"
pre_db_server="$db_server"
pre_ml_server="$ml_server"
# n秒待機
sleep $chk_range
done
}
### 関数定義 END ############################
### メイン処理 START ########################
# 引数取得
case $1 in
stop)
mode="stop"
;;
start)
mode="start"
;;
restart)
mode="start"
;;
*)
disp_help
exit 0
esac
# 引数が指定されていないときはHELPを表示して終了
if [ "$mode" == "" ]; then
disp_help
exit 0
fi
## 重複起動の回避
all_pid=`ps -A -l | grep $own_name`
edt_pid=`echo "$$
$all_pid"`
kill_pid=`echo "$edt_pid" | awk '{
if (NR == 1){
OWN=$1;
} else {
if ($4 != OWN){
if ($5 != OWN){
print $4" ";
}
}
}
}'`
if [ "$kill_pid" != "" ]; then
kill_prc $kill_pid
fi
# STOP時は終了
if [ "$mode" == "stop" ];then
exit 0
fi
# チェック処理
chk_app_main &
#html(</td><td valign="top" style="font-size:100%;">)
#html(</td></tr></table>)
#html(<table><tr><td colspan="2" style="font-size:100%;"> (3) 上記のシェルを /etc/init.d 以下に配置し、サービスとして初期起動するようにしておく。</td></tr><tr><td style="font-size:100%;">)
# cp chk_app /etc/init.d/
# chkconfig --add chk_app
# chkconfig --level 345 chk_app on
#html(</td><td valign="top" style="font-size:100%;">)
[補足]~
・チェック処理自体が止まってしまった時の為に、&br;
cronで定期的に実行するなどの工夫が必要かも。。~
#html(</td></tr></table>)