私はprefork
を使用して、Apache 2.2サーバー(Ubuntuサーバー10.04、8x2GHz、12Gb RAM)でPHP Webアプリケーションを実行します。Apacheは、毎日約100k〜200kのリクエストを取得します。約100〜200がタイムアウト制限に達すると(1000ごとに約1)、他のほとんどすべての要求はタイムアウトよりかなり下で処理されます。
これがなぜ起こるかを知るために私は何ができますか?それとも、すべてのリクエストの一部がタイムアウトするのが普通ですか?
これは私がこれまでに行ったことです:
見てわかるように、タイムアウト制限とより妥当な要求の間にある要求はほとんどありません。現在、タイムアウト制限は50秒に設定されていましたが、以前は300秒に設定されていましたが、同じ状況で、いくつかのタイムアウトが発生し、その後、他の要求に大きなギャップが生じました。
タイムアウトするすべてのリクエストはAJAX
リクエストですが、その大部分はリクエストであるため、おそらくそれは偶然です。 Apacheの戻りコードは200
、しかしタイムアウト制限に明らかに達しています。それらは、さまざまな異なるIPからのものです。
タイムアウトになるリクエストを確認しましたが、同じリクエストを1秒も経たないうちに実行しても、特別なことは何もありません。
さまざまなリソースを調べて、原因を見つけることができるかどうかを確認しましたが、運がありませんでした。常に十分な空きメモリ(最低でも約3GBの空き容量)があり、負荷が1.4と高くなり、CPU使用率が40%になることがありますが、負荷とCPU使用率が低い場合、多くのタイムアウトが発生します。ディスクの書き込み/読み取りは、日中ほぼ一定です。 MySQLのスロークエリログ(1秒を超えるものをログに記録するように設定)にはエントリがありません。リクエストがないため、データベースの書き込み/読み取りの数は多くありません。
青はCPU使用率で、ピークは40%で、栗色は負荷が1.4です。したがって、CPU使用率/負荷が低くてもタイムアウトが発生することがわかります(10秒のスパイクはCPU使用率によく対応していますが、これは別の問題です。これらの原因を特定する可能性が高いです)。
Apacheエラーログにエラーはなく、200を超えるアクティブなApacheプロセスに到達することはありません。
Timeout 50
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
<IfModule mpm_prefork_module>
ServerLimit 350
StartServers 20
MinSpareServers 75
MaxSpareServers 150
MaxClients 320
MaxRequestsPerChild 5000
</IfModule>
私はUbuntu 12.04.1に更新しました。念のため、変更はありません。私はmod_reqtimeoutを設定して追加しました:
RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500
現在、ほとんどすべてのタイムアウトは10秒で発生し、1つまたは2つは20秒で発生します。私はそれを受け取るのに問題があるリクエストボディを取得しているほとんどの場合を意味すると思いますか?リクエストの本文は数百バイトを超えてはいけません。私は1秒あたりのネットワークトラフィックを監視しており、1Mbit/sを超えることはなく、rxerrsまたはrxdorpsも表示されません。 HopelessN00bについて投稿しました。それはいくつかの悪いユーザー接続のケースである可能性がありますか?
1時間ごとのスパイク(上記のグラフでは1時間の33分後、現在は12分後)で、定期的に実行されているものがあるかどうかを確認しようとしました( cronなど)が見つかりませんでした。 PHPガベージコレクションは1時間に2回実行されますが、スパイク時には実行されません。それでも無効にしてみましたが、違いはありません。
私は--top-cpuおよびtopとともにdstatを使用して、スパイク発生時のプロセスを確認しました。表示されるのは、Apacheが数秒間懸命に動作しているだけですが、他のプロセスが重要なCPUを使用していません。
スパイクのグラフを拡大して作成しました。
私には、Apacheが数秒間停止し、停止中に発生したリクエストを処理するために一生懸命働いているように見えます。何がそのような停止を引き起こす可能性がありますか、それとも私はそれを誤解していますか?
私が最初に気づいたのは、最初のグラフを見て、問題の原因となっている可能性がある1時間ごとのスローダウン(1時間の約40分後に発生)があるようです。 OS /データベースのタスクスケジューラを確認する必要があります。
あなたが提供したデータに基づいて、私の次のステップは、応答時間の頻度(Y軸の応答数vs Xの継続時間)を調べることですが、タイムアウトを示すURL(またはできれば一度に1つのURL)のみを含めます)。典型的なシステムでは、これは通常またはポアソン分布に従う必要があります-タイムアウトしているリクエストは単にテールの一部である可能性があります-この場合、一般的なチューニングに注力する必要があります。 OTOHディストリビューションがバイモーダルの場合、コードのどこかで競合を探す必要があります。
私はこれについて別の考えを持っています。これは、1日に多数のリクエストを受け取り、ピーク時間中にのみタイムアウトがあるように見えるという事実に基づいています(投稿した写真から)。
Server Faultブログに投稿があります。Per Second Measurements Don't Cut It
...これらのリクエストの一部が、ServerFaultチームが遭遇したのと同じ問題に遭遇している可能性はありますか?
1 Gbit/sインターフェイスでパケットを10〜30 MBit/sの速度でかなり頻繁に破棄していると、パフォーマンスが低下することがわかりました。これは、10〜30 MBit/sのレートは、実際には5分あたりの転送ビット数を1秒のレートに変換したものだからです。 Wiresharkをより深く掘り下げ、1ミリ秒IOグラフ化を使用した場合、いわゆる1ギガビット/秒のインターフェイスのミリ秒あたり1メガビットのレートを頻繁にバーストすることがわかりました。