私のセットアップ:3つのほぼ同一のWebサーバーマシンで、DNSを介した単純なロードバランシングで同じ高負荷の動的Webサイトにサービスを提供しています。このサービスは、2年以上同じApache構成(Apache2、php5、ubuntu 8.04 linux 2.6.24-29-server)で動作しています。
私の問題:約2週間前から、この構成で問題が発生しています。ほぼ毎日、約5分間、Webサイトにアクセスできない小さな瞬間があります。引き続きssh経由でサーバーにログインできます。 htop
を実行すると、マシンは何もしないのがわかります。約1000のApacheプロセスが実行されていますが、CPUアクティビティがありません。
この状況をデバッグするために、Apache mod_statusを使用しました。プロセススコアボードは次のようになります。
_C.___K_______________________R._______.__K_K____K___C_______.__
_______C__________.___________________________________.________C
_.____K__________K___K_WK_____._K_____________________________._
W______K__________K________.____________________._______C_______
_C_.__K__K____.._.._____________________________________C_______
_R___________K___.______C________.C_________.______._____C______
____________KKC____K_____K__WC_________________C_____.__.____.__
_____________________C_________K______.____C______._____________
_.___C____.___.___________________________.K______.____K________
W__.___________________C.__.____K________K_______R_._.__._______
__C__C_.__________C__C_______._____W______________C_.___C_______
____.______C_____________C________.____C____________.________._K
__.__________.K_____________K_________._____C____.K__________KW_
__K.W________R_________._______.___W___________.____.__K_____W__
W___.___..________W____K
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"C" Closing connection, "L" Logging, "G" Gracefully finishing,
"I" Idle cleanup of worker, "." Open slot with no current process
したがって、ほとんどのプロセスは接続を待機しています。約5分後、状況は通常に戻ります。すべてのマシンでプロセスが最も少なく、ほとんどのワーカーは「。」ステータス(リクエストを処理するために開いていることを意味します)を持ち、もちろんWebサイトにアクセスできます!
ログで何かを見つけようとしていますが、何もありません。Apacheアクセスログは約4分間サイレントで、エラーログも同じです。また、他のシステムログで何も問題を見つけ出すことはできません。
状況は3つすべてのWebサーバーで同じです(それらすべてに同時にこの負荷ピークと無応答状態があります)、これはハードウェアに関連していることではありません。しかし、これはネットワーク(tcp)の問題に関連している可能性があると思います。
何か案は?
編集:私が発見したいくつかの詳細情報:
この問題は再び発生し、ローカルで接続できないことを確認できました。
それが起こった後、私は次のコマンドでいくつかの接続統計を作成しました:netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
後で同じコマンドを実行すると、次のようになります。
そのため、通常の状況では、現時点でApacheによって処理されているクライアントによる接続は100〜200しか開いていません。この「クラッシュ」が発生すると、接続数が増えます。これを分析する最良の方法は何ですか?
EDIT2:Apache2.confの重要な行は次のとおりです。
KeepAlive On
MaxKeepAliveRequests 20
KeepAliveTimeout 1
<IfModule mpm_prefork_module>
ServerLimit 920
StartServers 30
MinSpareServers 80
MaxSpareServers 120
MaxClients 920
MaxRequestsPerChild 700
</IfModule>
これは、php_modを使用したApache2プリフォークです。
サーバーには8GBのRAMと4GBのスワップパーティションがあります。
現在のホストと処理中のリクエストを監視するには、mod_statusの拡張ステータス( http://httpd.Apache.org/docs/2.2/mod/mod_status.html#extendedstatus )を有効にする必要があります。接続を解放するのに時間がかかりすぎて接続がスタックするスクリプト/ページがあると思います。
まず、プロセスのMax open files
制限を確認します。アクティブなソケット接続は、開いているファイルとしてカウントされます。 cat /proc/###/limits
は、別のプロセスの実効値を確認するための良い方法です。 lsof -p ###
を使用して、開いているファイルのリストを取得できます。ここで、###はWebサーバーのプロセスIDです。 lsof -p ### | wc -l
を比較して、限界にどれだけ近づいているかを確認できます。制限に達している場合は、Apacheのerror_logにもメッセージが表示されます。
ソケット接続ごと、およびcgiスクリプトまたはデータファイル参照ごとにファイルハンドルが必要です。 920 MaxClientsの場合、httpdプロセス用に少なくとも4,000ファイルを構成する必要があります。 /etc/security/limits.d/に以下の内容のファイルを追加すると、ファイルの数を増やすことができます。ユーザー名が、Webサーバーで使用しているものと一致することを確認してください。
Apache soft nofile 10000
Apache hard nofile 10000
次に、ポートの枯渇が問題である場合は、/ etc/sysctl.confのいくつかのIP設定を調整できます。 (net.ipv4.tcp_fin_timeout
で始まる)。これは通常、非常に小さな接続が多数ある場合にのみ問題になります。多くのTIME_WAITソケットはこれの1つのインジケータですが、これはpossible SYN flooding
およびSending cookies
に関するsyslogのエラーが伴う場合にのみポートの枯渇を示します。また、サーバーがファイアウォールの背後にあり、悪意のあるSYN攻撃を阻止できることを確認してください。
また、prefork MPMでは、各プロセスのメモリスペースにPHPがあることを覚えておいてください(メモリ制限の設定は?)。ワーカーMPMに変更してみてください。わずかに異なるPHPモジュールが必要になる場合があります。
また、外部モジュールのApache構成をトリミングするためのリモートイヤリングの価値もあります。
私の経験では、そのようなことは、検索エンジンクローラーのようなもの、またはARPの競合のようなものによって引き起こされます。または、ネットワークの一部の関連部分のトラフィックレベル。
Sarは便利だと思うかもしれません...とてもフレンドリーではありませんが、確かに便利です。
おそらくioにも関連しています。 Sarは、(ディスクアクティビティを記録するように構成している場合)平均IO待機時間を教えてくれます。 IO待機時間を一番上に表示することもできます(これはパーセンテージであり、実際の意味を確認してください)。SANまたは仮想環境。
Apache MPM設定とキープアライブ設定を表示します。
それはおそらくこれらの悪い組み合わせです。
編集:私はあなたがphpについて言及したのを見ました。
これがmod_phpである場合、そのマシンは64 GBのメモリを搭載していると、2500接続を維持できません。