- ベストアンサー
load averageの値を監視して自動でコマンドを実行するには?
- Redhat Linuxで自宅サーバーを運用しており、load averageの値を監視して特定のコマンドを自動で実行したいです。
- load averageは1分、5分、15分の平均値を示し、1分の平均値が30を超えた場合にコマンドを実行したいです。
- cronでは最短でも1分おきにしかコマンドを実行できないため、毎秒load averageを監視して1分平均が30を超えたら即座にコマンドを実行したいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
数え間違いをしてましたm(_ _)m 10番目ですね。心配したのはアップタイムが一日未満の時にずれるのではと思いました。ずれる心配のない、/proc/loadavg が良いですね。 わかりにくかったようなので、ワンステップずつ書いてみます。test コマンドでは実数の比較が出来ないので、小数点以下を削除して整数部分だけ比較することにしています。 #!/bin/bash A=(`cat /proc/loadavg`) # A[0]=1分平均、A[1]=5分平均、A[2]=15分平均 B=${A[0]} # B=1分平均を実数のまま C=${B/.*/} # その文字列のピリオドとそれに続く文字を削除・・・切り捨てて整数化する if test $C -gt 30 then killall xxxxx echo "$C 件だったのでkillallしました" | /bin/mail -s "killall notice" root fi > hello.cgi のみ時々異常回数呼び出され、 cgi側で、ロックファイルなどを使って、「すでにに30多重動いていればエラー画面を返す」ように書き換えた方が良いように思います。 プログラミングのその言語のカテゴリで、 その旨を聞いてみればどうでしょうか? load average というのは「CPUをもらっている」or「CPU待ち」のプロセス数なので、「ディスクやネットやの入出力待ち等」のプロセスは入りません。
その他の回答 (2)
- notnot
- ベストアンサー率47% (4900/10358)
cgiプロセスはIP通信をしません。Apacheがクライアントと通信して、データを受け取ったら、cgiプロセスを起動して、環境変数とパイプ経由でデータをcgiプロセスの標準入力にわたし、cgiプロセスは標準出力をパイプ経由でapacheにわたし、apacheはそれを処理結果としてクライアントに送ります。 従って、試みられた方法は無意味です。 cgiの中では環境変数 REMOTE_ADDR にクライアントのIPアドレスが入りますから、cgiの開始時と終了時に、 時刻・開始/終了・プロセスID・REMOTE_ADDR をsyslogにでも記録すると、何らかの手がかりがあるかもしれません。 具体的な方法は、その言語のカテゴリで聞いてください。 一応、ありがちな原因として、cgiプログラムがループして居座っているという可能性は無いのですか?
補足
なるほど、どおりでnetstatでは見つからなかったわけですね。 大変勉強になりました。 >cgiの中では環境変数 REMOTE_ADDR にクライアントのIPアドレスが入りますから、cgiの開始時と終了時に、 時刻・開始/終了・プロセスID・REMOTE_ADDR をsyslogにでも記録すると、何らかの手がかりがあるかもしれません 具体的な方法は、その言語のカテゴリで聞いてください。 そういう方法もあるんですね。 cgiがループしている可能性は、よくわかりません。。 1日中、普通に動いていながら、だいたい毎日同じ時間帯に大量起動が発生するため、プログラム自身に問題があるわけではなく、誰かの悪意あるアクセスなのかなと思いました。 今回は色々勉強になり助かりました。ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10358)
#!/bin/bash # bashを前提 A=(`uptime`) # 配列Aにuptimeの結果をバラして格納 B=${A[10]/.*/} # 11番目(添え字は0からなので10)が1分平均。そのピリオド以降を削除してBに if test $B -gt 30 then killall xxxxx fi こんな感じですかね。ただしuptimeの11番目が常に1分平均かは未確認。前半の表示結果次第で変わるのかも。 ただ、cgiの数を制限したいのなら、apacheのconfファイルでプロセスやスレッドの最大値を制限した方が良いのでは?
補足
ご回答ありがとうございます。1分平均が何番目か、について、 $ uptime では常に、 14:23:08 up 34 days, 4:06, 1 user, load average: 0.67, 0.63, 0.58 というフォーマットで表示されます。よって1分平均の値は10番目、 $ uptime | gawk '{ print $10 }' と打つと、常に以下のように コンマ付きで1分平均の値が表示されました。 0.67, つまり添え字が0からということだと、正しくは9番目以降を削除して。。となるのでしょうか。 また、コンマを消すために、 (B=${A[9]/,*/}) でしょうか? 1分平均の値は他にも /proc/loadavg の1番目に表示できました。 $ cat /proc/loadavg と打つと、 0.79 0.71 0.62 3/161 25388 このコマンドを使う場合は・・ 添え字が0からなので、1番目のスペース以降を削除して。。 #!/bin/bash A=(`cat /proc/loadavg`) B=${A[0]/``*/} if test $B -gt 30 then killall xxxxx fi でしょうか? あと、killall xxxxx したら、root宛に通知メールを送りたいのですが どのように記述すればよいでしょうか。 (root 宛のメールは、外部のメールアドレスに転送されるようにしてあります) >ただ、cgiの数を制限したいのなら、apacheのconfファイルでプロセスやスレッドの >最大値を制限した方が良いのでは? はい、確かに killall は根本的な解決ではありません。 hello.cgi のみ時々異常回数呼び出され、 その接続元もどうしても特定できず、 サーバーが不安定になります。とりあえずkill したいと考えています。
補足
完璧に動作しました。本当にありがとうございました。 hello.cgi について、これを異常回数呼び出しているのは 特定の接続元だと思うのですが、もしkillせずに30以上 動いている場合はエラーを返すようにcgiを書き換えると、 こやつのみに、hello.cgi が占有されてしまう気がします。。 こやつが誰なのか一生懸命探っているんですが分かりません。 topで監視していると hello.cgi がズラッと並ぶんですが、 これらの接続元IPを知るにはいったいどうしたらよいでしょうか。 別の質問になってしまいますが、もしアドバイスいただけましたら うれしいです。 ちなみに $lsof -i:80 |grep -v LISTEN とか $netstat -np |grep httpd とかを watchコマンドで 1秒間隔で監視していますが、 hello.cgi へアクセスしているIPというのは直接表示されず 補足出来ません。(apache のプロセスを表示しているはずなんですが・・) また、top で拾ったhello.cgi のPID を、即座に netstat -p | grep PID を使って接続元を特定しようとしますが PID は一瞬で変わり消えてしまうため補足出来ません。 アクセスログも当然監視していますが、同じIPがズラズラ表示されることもなく、 どういった種類のアクセスがこういった異常を引き起こすのか悩んでいます。