私は、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の土地?
次の手順は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を呼び出す必要があります。
install PHP xdebug extension and enable tracing log とします。これにより、実行されたすべての関数の統計を含むファイルが作成されます-完了までにかかった時間、消費されたメモリの量、その関数を含むファイルへのパスなど。
このデータは、修正が必要な機能を特定するのに役立ちますが、完全なトレースログのサイズが急速に大きくなるため、アプリケーションの一部のみをトレースする必要がある場合があることに注意してください(上記のガイドでも説明しています)...