私は本当に奇妙な問題に遭遇しましたが、それをさらにデバッグする方法がわかりません。NGINX + PHP5-FPM + APC Amazon Ubuntuインスタンスがあり、複雑なPHPフレームワークであるWebサイトがインストールされています。問題をデバッグしようとしている間、フローをこれに減らしました:多くの大きなクラスが含まれ、メインオブジェクトが作成され、セッションが開始され、構成の配列がmemcachedから取得され、XMLファイルがmemcachedから取得されます。HTMLテンプレートが含まれ、出力がクライアントに送信されます。
次に、http_load
ツールを使用して、Webサイトに1秒あたり20リクエストの負荷をかけます。http_load -timeout 10 -rate 20 -fetches 10000 ./urls.txt
次に起こることはかなり奇妙です。top
は、それぞれがCPUの数%を使用して生成された一連のphp5-fpmプロセスを示しており、次のようにすべてがスムーズに実行されます。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28440 www-data 20 0 67352 10m 5372 S 4.3 1.8 0:20.33 php5-fpm
28431 www-data 20 0 67608 10m 5304 S 3.3 1.8 0:16.77 php5-fpm
28444 www-data 20 0 67352 10m 5372 S 3.3 1.8 0:17.17 php5-fpm
28445 www-data 20 0 67352 10m 5372 S 3.0 1.8 0:16.83 php5-fpm
28422 www-data 20 0 67608 10m 5292 S 2.3 1.8 0:18.99 php5-fpm
28424 www-data 20 0 67352 10m 5368 S 2.0 1.8 0:16.59 php5-fpm
28438 www-data 20 0 67608 10m 5304 S 2.0 1.8 0:17.91 php5-fpm
28439 www-data 20 0 67608 10m 5304 S 2.0 1.8 0:23.34 php5-fpm
28423 www-data 20 0 67608 10m 5292 S 1.7 1.8 0:20.02 php5-fpm
28430 www-data 20 0 67608 10m 5300 S 1.7 1.8 0:15.77 php5-fpm
28433 www-data 20 0 67352 10m 5372 S 1.7 1.8 0:17.08 php5-fpm
28434 www-data 20 0 67608 10m 5292 S 1.7 1.8 0:18.56 php5-fpm
20648 memcache 20 0 51568 8192 708 S 1.3 1.3 2:51.06 memcached
28420 www-data 20 0 69876 13m 6300 S 1.3 2.3 0:20.89 php5-fpm
28421 www-data 20 0 67608 10m 5300 S 1.3 1.8 0:21.19 php5-fpm
28429 www-data 20 0 9524 2260 992 S 1.3 0.4 0:11.68 nginx
28435 www-data 20 0 67608 10m 5304 S 1.3 1.8 0:18.58 php5-fpm
28437 www-data 20 0 67352 10m 5372 S 1.3 1.8 0:17.87 php5-fpm
28441 www-data 20 0 67608 10m 5292 S 1.3 1.8 0:20.75 php5-fpm
次に、1秒から数分の間のどこかになり得るしばらくすると、いくつかの(通常は2つの)php5-fpmプロセスが突然すべてのCPUを消費します。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28436 www-data 20 0 67608 10m 5304 R 48.5 1.8 0:23.68 php5-fpm
28548 www-data 20 0 67608 10m 5276 R 45.2 1.7 0:07.62 php5-fpm
28434 www-data 20 0 67608 10m 5292 R 2.0 1.8 0:23.28 php5-fpm
28439 www-data 20 0 67608 10m 5304 R 2.0 1.8 0:26.63 php5-fpm
この時点で、すべてがスタックし、すべての新しいHTTP要求がタイムアウトします。http_loadツールを停止すると、php5-fpmが何分間もハングします。興味深いことにphp5-fpm stop
、そうすると、php5-fpmプロセスは消えますが、ファイルシステムを使用するコマンドは実行に問題があります。たとえば、ssh経由でファイルをダウンロードしようとするとtop
、次のように表示され、実際のダウンロードを開始するのに何分もかかります。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3298 sshd 20 0 7032 876 416 R 75.2 0.1 0:04.52 sshd
3297 sshd 20 0 7032 876 416 R 24.9 0.1 0:04.49 sshd
PHPエラーログには通常次のようなものがあります。
[05-Dec-2012 20:31:39] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 58 total children
[05-Dec-2012 20:32:08] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 66 total children
Nginxエラーログは次のエントリで溢れています:
2012/12/05 20:31:36 [error] 4800#0: *5559 connect() to unix:/dev/shm/php-fpm-www.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: ..., server: ec2-....compute-1.amazonaws.com, request: "GET /usa/index.php?page=contact_us HTTP/1.0", upstream: "fastcgi://unix:/dev/shm/php-fpm-www.sock:", host: "ec2-....compute-1.amazonaws.com"
PHP-FPMの遅いログには興味深いものは何も表示されず、スワッピングは発生せず、問題に関する他の興味深い事実を収集することはできませんでした。私は設定ファイルの変更を何度も繰り返しましたが、最新のものは
nginx.conf: http: //pastebin.com/uaD56hJF
pool.d/www.conf: http: //pastebin.com/mFeeUULC
===更新1===
サイトの設定:http://pastebin.com/qvinVNhB
===更新2===
dmesg
また、このようなエラーを報告することがわかりました
[6483131.164331] php5-fpm[28687]: segfault at b6ec8ff4 ip b78c3c32 sp bff551f0 error 4 in ld-2.13.so[b78b5000+1c000]
===更新3===
念のため、ハードウェアの問題を排除するために、新しいAmazonEC2マイクロインスタンスを用意しました。また、現在php-fastcgiを使用して、fpmのバグの可能性を排除しています。その他の違いはわずかですが、変更されるのはUbuntu->Debianだけだと思います。サーバーがmax_execution_time秒後にわずかに回復する(そして再びスパイクする)ことを除いて、同じ問題が引き続き発生します。
別のtest.phpで遊んでみましたが、同じ問題かどうかはわかりませんが、少なくともtop
同じように見えます。test.phpを作成し、フレームワークに属する一連のライブラリを含めました。ライブラリは、クラスを定義するか、クラスを定義する他のライブラリを含めることを除いて、何もしません。私はAPCに確認しましたが、これらすべてがAPCによって正常に処理されます。私は毎秒200リクエストでtest.phpにプレッシャーをかけ始めましたが、しばらくすると同じことが起こりました。それを除いて、「開いているファイルが多すぎます」というエラーが発生しました。ただし、常に発生するとは限りません。エラーを出力せずにタイムアウトが開始され、いくつかのphpプロセスがスタックしてすべてのCPUを消費する場合があります。私はそれで少し遊んだだけですが、ここには相関関係があると思います-含まれるライブラリの数またはわずかに変化するリクエスト/秒レートを制御することで、CPUスパイクがいつ発生するかを制御できます。
fs.file-max = 70000
...
* soft nofile 10000
* hard nofile 30000
...
worker_rlimit_nofile 10000;
...
(reloaded all the configs and made sure the new system vars actually took affect)
したがって、これまでに思いついた次善の唯一の説明は、APCはメモリからファイルをプルすることになっていますが、内部的には、PHPinclude-sが呼び出されるたびにファイル記述子を使用する方法で実装されているということです。そして、遅延してリリースするか、不幸な瞬間に同時に到着するリクエストが多すぎるため、システムは記述子を実行し、新しく到着したHTTPリクエストはすぐに巨大なキューにスタックされます。どういうわけかこれをテストしてみます。