あなたの映画力を試せる!POPLETA映画検定(無料) >>

Redhat Linux で自宅サーバーを運用しています。

コマンド top,uptime,w などで見れる load averageについて、

load average: 0.77, 2.39, 3.38 (1分、5分、15分の平均数値)
このように表示されますが、

load average の1分の平均が 例えば 30 を超えたら、
特定のコマンド(killall hello.cgi)を自動で実行したいと思っています。

さらさらっとサンプルスクリプトを書いて頂けたら
大変嬉しいのですが。。

あと、このスクリプトを実行する方法ですが、
cronだと、たぶん最短間隔でも1分おきにしか
走らせることは出来ないと思います。
極端な話、毎秒、バックグラウンドで常に load average を監視して
1分平均が 30 を超えたら、即座に killall hello.cgi を実行したいです。

どなたかお知恵を拝借下さい。宜しく御願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (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待ち」のプロセス数なので、「ディスクやネットやの入出力待ち等」のプロセスは入りません。

この回答への補足

完璧に動作しました。本当にありがとうございました。

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がズラズラ表示されることもなく、
どういった種類のアクセスがこういった異常を引き起こすのか悩んでいます。

補足日時:2007/12/30 01:51
    • good
    • 0

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日中、普通に動いていながら、だいたい毎日同じ時間帯に大量起動が発生するため、プログラム自身に問題があるわけではなく、誰かの悪意あるアクセスなのかなと思いました。

今回は色々勉強になり助かりました。ありがとうございました。

補足日時:2007/12/31 00:12
    • good
    • 0

#!/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 したいと考えています。

補足日時:2007/12/29 14:00
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QCPU使用率とロードアベレージ

Linuxのtopコマンド等で出力されるCPU使用率とロードアベレージの違いを教えてください。
また、ロードアベレージをCPU使用率に換算することは可能でしょうか?
可能であれば方法を教えてください。

Aベストアンサー

 ロードアベレージは、最も簡単に説明すると、実行プロセス数の平均だ。説明によっては実行待ちプロセス数や実行可能プロセス数となっているが、正確には実行プロセス数(実行中プロセス数+実行可能プロセス数)だ。つまり、I/O待ちのプロセスはカウントされない。
 ここで、たとえば、1秒間に10回実行プロセス数をカウントすると、1分間では600回カウントする。カウントした時に、毎回3、4、5あたりをうろうろしていると、平均値としては4ぐらいになる。これがロードアベレージだ。正確に、Linuxが1秒に何回カウントしているかは知らんが、どちらにせよ
(カウントした時のロード数1+...カウントした時のロード数n)/カウント数
という計算式になるので、1分に何回カウントしたかはあまり重要な数字ではない(もちろん1分に1回やら数回やらというのは困るが)。ロードの平均値を取っているのでロードアベレージだ。

 ロードアベレージは、「システム負荷率」と表現される事が多い。負荷ってCPU使用率じゃないのと思うかも知れないが、例えば、CPUが1個のマシンにおいて、CPU使用率が常に100%の状態が1時間続いたと仮定して、その間ロードアベレージが常に1だったとすると、システムの負荷は0という事になる。なぜかと言うと1個のプロセスが常にCPUを占有している状態だからで、それは1個のプロセスが理想的にCPUを使いつづけた状態だからだ。
 つまり、ロードアベレージが負荷と表現されるのは、「CPUが割り当てられたらすぐ実行できるのに実行できないプロセスの割合」だからかな。

 別のモデルを考える。I/Oを行わず、常にCPUによる処理をしている3つのプロセスがあり、システムプロセスを含め、それ以外のプロセスは一切動作しないとすると、ロードアベレージは常に3になる。CPUが1個だと3、2個だと3、3個だと3、4個だと3だ。変わってCPU利用率はCPUが1個だと100%、2個だと100%、3個だと100%、4個だと75%となる。
 もちろん、ロードアベレージが3でも、CPUが1個だと常に2つのプロセスが実行可能(CPU割り当て待ち)となるが、3個だと3つのプロセスが全て実行中になる。なので、CPU利用率は1個でも3個でも同じ100%だが、3個だと十分仕事をさばけている状態だし、1個だとさばけていないよね。CPU利用率だけでは分からないって事。なのでロードアベレージが存在するわけだ。
 そういう訳で、「ロードアベレージの理想値=CPUの個数」または、「ロードアベレージがCPUの個数を超えなければシステムは良好」などと説明されている訳だな。

 これが、私が解釈しているロードアベレージだが、何か参考になれば。

 ロードアベレージは、最も簡単に説明すると、実行プロセス数の平均だ。説明によっては実行待ちプロセス数や実行可能プロセス数となっているが、正確には実行プロセス数(実行中プロセス数+実行可能プロセス数)だ。つまり、I/O待ちのプロセスはカウントされない。
 ここで、たとえば、1秒間に10回実行プロセス数をカウントすると、1分間では600回カウントする。カウントした時に、毎回3、4、5あたりをうろうろしていると、平均値としては4ぐらいになる。これがロードアベレージだ。正確に、Linuxが1秒に何回カ...続きを読む

Qダブルクォーテーション囲いカンマ区切り形式で保存したい

お願いします。
エクセル2000使用してます。
【質問1】
"名前A","ナマエA","09011111111","aaa@docomo.ne.jp"
"名前B","ナマエB","09011111112","bbb@docomo.ne.jp"
"名前C","ナマエC","09011111113","ccc@docomo.ne.jp"
このように、ワークシートをダブルクォーテーション囲いカンマ区切り形式で保存するにはどうすればよいでしょうか。

【質問2】
上記のデータを読み込むときに電話番号部分の先頭の0が取れてしまうの防ぐために、ファイルの拡張子をtxtにリネームしておいて、エクセルから開くときにウィザードで列のデータ形式を文字列と指定しています。もっと簡単な方法が教えてください。(頻繁にファイルを開くので。。。)

Aベストアンサー

1.マクロを使わないと出来ません。
  こんな感じです。
 Open "CsvFileName.csv" for Output as #1
 For Row = 1 to 10
  For Col = 1 to 10
   Select Case Col
    Case 1
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case 2
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case Else
     Print #1 Cell(Row, Col).Text;
   End Select
   If Col = 10 Then
    Print #1, ""
   Else
    Print #1, ",";
   End If
  Next Col
 Next Row
 Close #1

2.マクロを使えば自動化できます。
「データ」メニューの「外部データの取り込み」で「テキストファイル」を指定してCSVファイルを選択します。
テキスト取り込みウィザードで列のデータ形式を文字列と指定します。
上記の操作を「マクロの記録」でマクロにしてから
実用になるようにマクロを修正します。

1.マクロを使わないと出来ません。
  こんな感じです。
 Open "CsvFileName.csv" for Output as #1
 For Row = 1 to 10
  For Col = 1 to 10
   Select Case Col
    Case 1
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case 2
     Print #1 Chr$(&H22) & Cell(Row, Col).Text & Chr$(&H22);
    Case Else
     Print #1 Cell(Row, Col).Text;
   End Select
   If Col = 10 Then
    Print #1, ""
   Else
   ...続きを読む

QLinux 月を英語表示したい

し初歩的な質問で、申し訳ない

#!/bin/sh

date "+ %h"

で、月を英語表示させたいのですが

日本語で10月と出てしまいます

Aベストアンサー

#!/bin/sh
LANG=C
date "+ %h"

または

#!/bin/sh
env LANG=C date "+ %h"

Qhttpdの子プロセスがゾンビ化する原因

httpdは複数の子プロセスを生成しますが、この子プロセスがゾンビプロセス化してしまう
ことがあります。
このゾンビ化してしまう原因として考えられるものを教えて下さい。

『何らかの理由で子プロセスが停止せずに親プロセスが停止した』等、あいまいな答えでも
構いません。もちろん具体的であれば、とても助かりますが…。

思いつく限りいくつでも構いませんので、教えて下さい。

ちなみに、私が使用しているマシンで上記現象が発生している訳ではなく、一般的な事例として
子プロセスのゾンビ化の原因になり得る事象を知りたいと思っていますので、構成情報などは
あまり気にせずに答えて頂けると幸いです。

よろしくお願いします。

Aベストアンサー

ゾンビプロセス一般について書きます。

ゾンビプロセスとは、プロセスの実体は無いが、プロセステーブル(カーネルがプロセスを管理してる台帳)に
エントリーがある状態を指します。

名簿に名前があるけど、本人は居なくなっちゃってる、と。

あるプロセスが終了したときには、必ず一瞬でもこの状態になります。
通常は、プロセスが終了したというシグナルが親プロセスに通知され、親プロセスが後始末を
してあげて、めでたくゾンビ状態ではなくなるのです。

もし、親がシグナルを受けたときに適切な処理を行っていなければ、親プロセスが終了するか
システムが再起動するまで、ゾンビ状態のままです。

> このゾンビ化してしまう原因として考えられるものを教えて下さい。

子プロセスからのシグナルを受けたときの処理がまずい、のが原因です。


人気Q&Aランキング

価格.com 格安SIM 料金比較