web-dev-qa-db-ja.com

本番サーバーでスタックしたApache / phpスレッドのデバッグ

私は、Apache httpdとPHP _LoadModule php5_module /usr/lib/Apache2/modules/libphp5.soを使用してロードされるLinuxシステムを持っています。

Apacheのmod_statusモジュールを有効にしましたが、特定のスレッドが昨日から何かをしているのが止まっています。また、ps -axu | grep Apacheを実行してこれを確認します。これにより、多くのスレッドの中で、特定のスタックスレッドが発生します。

www-data  5636  0.0  0.1 423556 23560 ?      S    XXXXX   0:04 /usr/sbin/Apache2 -k start

XXXXXは昨日であるJan02のようなものであることに注意してください。また、pid(5636)は、Apacheのmod_statusページに表示されるスタックスレッドのpidと一致します。

私の質問は、PHPコードのどこにスタックしているのかを正確に確認するために、スレッドダンプまたは類似のものをどのように実行できますか?多分それは何かを待っています(i/o、ネットワーク、 db)しかし、私は何を知りません。

Javaの世界では、kill -3 pidを実行して、その特定のスレッドがスタックしている場所を明確に表示する、可読性の高いスレッドダンプを取得します。同様の手法がありますか? PHPの土地?

5
cherouvim

次の手順はLinux中心です。

  • 障害のある/スタックしたプロセスを特定する

あなたの場合、プロセスはSの状態にあり、_man ps_から意味します。

S割り込み可能なスリープ(イベントの完了を待機)

そのため、はい、おそらくネットワークまたはファイルシステムの操作が完了するのを待っています。

  • straceを使用してシステムコールとシグナルをトレースする

次のコマンドを実行して、straceプログラムをハングしているスレッドにアタッチします。

#strace -p 

これにより、リアルタイムでアクション、より正確にはプログラムによって実行されたsyscallsが表示されます。たとえば、open()は、特定のファイルが存在しないことを意味するENOENTなどのエラーを返します。

psの出力は、プロセスがCPU(3列目)を消費していないことを示しているため、ここでの問題はおそらくループに関係なく、ロックされたファイル、ソケットまたは外部アクションの待機などの待機中の操作に関連している可能性があります。

  • killとコアダンプ

実行中のプログラムに特定のシグナルを送信するために使用されるkillプログラムは、Javaに関連しているわけではなく、プログラムを閉じてSIGQUITファイルを生成するシグナル3(core)を送信するために使用できます。 coreファイルの生成は、正しいulimit権限が設定されている場合にのみ許可されます。_ulimit -c_コマンドで確認してください。 _0_と表示されている場合は、たとえばunlimitedに変更する必要があります。

 ulimit -c unlimited 

その場合にのみ、アプリケーションを再起動し、_kill -3_を送信してcoredumpを呼び出す必要があります。

2
iMil

install PHP xdebug extension and enable tracing log とします。これにより、実行されたすべての関数の統計を含むファイルが作成されます-完了までにかかった時間、消費されたメモリの量、その関数を含むファイルへのパスなど。

このデータは、修正が必要な機能を特定するのに役立ちますが、完全なトレースログのサイズが急速に大きくなるため、アプリケーションの一部のみをトレースする必要がある場合があることに注意してください(上記のガイドでも説明しています)...

1
Anubioz