web-dev-qa-db-ja.com

ApacheとPHP&MysqlとのCLOSE_WAIT接続の原因を突き止める

まず、ここに少しコンテキストがあります。

カスタムビルドのPHP Apacheアプリケーションで実行され、ウェブサイトをサポートするアプリケーションがあります。

現在、私たちのウェブサイトではトラフィックが多いです。現在の設定は次のとおりです。-ロードバランサーの背後にある10台のLinuxWebサーバー(各サーバーには8台のCPU、30 Go RAMがあります)-1台のLinux mysqlデータベースサーバー(30台のCPU、120台のGo RAM)

ほとんどの場合、トラフィックは正常に保持されますが、理由が不明な場合は、アクティブなmysql接続の総数が急増することがあります。最大値に達するまでリークが続き、最終的にアプリケーションがWebユーザーによって使用できなくなります。

これが発生した場合、負荷平均、メモリ、CPU使用率、ディスクスワップの観点から、すべてのサーバーは問題ありません。彼らは利用可能なリソースをたくさん持っています。

CLOSE_WAIT接続状態のApacheプロセスがたくさんあることに気づきました。 Webサーバーの1つで、その状態で約600のプロセスが見られました。

これは、発生している問題の症状のようです。しかし、深く掘り下げることは困難です。これが私の質問です:

  • Apacheがこれらのプロセスに依存しているのはなぜですか?
  • その原因を突き止めるために使用できるツールやデバッグ手法はありますか?
  • 何が起こっているのかを理解するために、どのような指標を見る必要がありますか?

よろしくお願いします。

5
ssense

他のmysql接続が必要以上に長い間更新しようとしているテーブルまたは一部の行をロックしているクエリがあると思います。それが発生すると、最大接続数に達するまで、すべての着信要求がその背後にスタックします。

(データベースでクエリがブロックされているために)要求が受信され、応答が受信されないため、Apache側でも同じことが発生しています。 PHPはデータベースへの接続が開いています。クエリを実行し、まだ応答を受信して​​いません。その時点でのApacheの「ハング」は、待機しているため、期待どおりの結果です。答え。

すべてのサーバーで利用可能なすべての子がデータベースの応答を待機しているため、Apacheは外部(ブラウザー/モバイルアプリなど)からハングしているように見えます。文字通り、利用可能な接続はこれ以上ありません。 (これは、ロードバランサーに設定された接続制限でもあります)。まだ行っていない場合は、ロードバランサーで状態変更のログ記録を開始します。 「雷鳴の群れ」の問題(後で説明)が発生している間、各Webサーバーが繰り返し上下するのを目にする可能性があります。

CLOSE_WAITでの接続は症状であり、問​​題ではないと思います。考えられるより明白な問題(データベース)に対処するまで、その角度のトラブルシューティングに時間を費やすことはありません。膨大な数のCLOSE_WAITがなくなることを修正すると、オッズが発生します。

データベース側でトラブルシューティングを開始するには、まだ有効にしていない場合は、 遅いクエリログ を有効にする必要があります。 1秒程度にわたってリクエストをログに記録し、問題が発生したときに何が表示されるかを確認します。

注:遅いクエリログは、クエリが完了するまでクエリをログに記録しません。問題の開始時に最初に表示されるクエリが問題クエリであると想定しないでください。そうかもしれないし、そうでないかもしれません。

これで、他のクエリをブロックしている問題のあるクエリが終了すると、Webサイトが通常に戻ることが期待できます...

そうではありません。 500リクエスト/秒が定期的に受信され、たとえば合計1000リクエスト/秒を処​​理でき、クエリがデータベースを10秒間ロックする場合。まだ入っている500 /秒に加えて、処理待ちの要求が5,000あります。これは Thundering Herd problem として知られています。

あなたの問題はまったく別のものである可能性がありますが、これらは私が何度も扱ってきた問題とまったく同じ症状であり、ほとんどの場合、問題は他のクエリをブロックするデータベースクエリでした。データベースが原因ではないこの問題に出くわしたのは、CentOS(RHELにも問題があります)だけです。あなたがそれらを検索する場合。これが本当かもしれないと思うなら、テストするのは非常に簡単です。必要なのは resolv.confに1行追加する です。

問題が発生したときに、同じ時刻に、または同じ時刻に問題が発生しているように見える場合は、cronジョブ(または設定されたスケジュールで実行されている他のジョブ)をチェックして、問題のクエリが送信されているかどうかを確認する。

最後に、雷鳴の群れの問題に噛まれていると判断した場合は、ロードバランサーに制限を設定することをお勧めします。サーバーのベンチマークを行って、サーバーが同時に処理できるリクエストの最大数を大まかに決定し、ロードバランサーが各バックエンドWebサーバーへの接続数を超えないように制限する必要があります。

幸運を。

6
yoonix