老眼鏡をかけてください。これは長めの眼鏡になります。
まず、私がしていること。私はいくつかの特に遅いtcpデバイス用のウェブアプリインターフェースを構築しています。それらへのソケットを開くには200ミリ秒かかり、fwrite/freadサイクルにはさらに300ミリ秒かかります。各リクエストでこれらの両方のアクションの必要性を減らすために、前述の200msだけ応答時間を短縮する永続的なtcpソケットを開いています。 PHP-FPMが異なるクライアントからのリクエスト間で永続的な接続を共有することを望んでいました(実際にそうです!)が、2日間のインターネット接続、ログの読み取り、設定の変更の後で解決できなかった問題がいくつかあります。でも少し絞り込みました。
セットアップ:
Relevent config:
nginx
php-fpm/pool.d
何が起こるかについて、大まかな詳細から細かい詳細に移りましょう。新たに開始した後、4xnginxプロセスと2xphp5-fpmプロセスがリクエストの処理を待機しています。次に、数秒ごとにスクリプトにリクエストを送信します。最初はソケット接続を開いて約500msでデータを返し、2番目は300msでデータを返し(ソケットを再利用しています)、3番目も約300msで成功し、4番目のリクエスト= 502 Bad Gateway 、5日と同じ。 6番目のリクエストは、500ミリ秒かかったことを除いて、もう一度データを返します。このプロセスは数サイクル繰り返され、その後4つの要求ごとに2x502の不良ゲートウェイと2x500msのデータ応答が発生します。
すべてのfpmプール値を2倍にし、4x php-fpmプロセスを実行している場合、サイクルは4x成功した500ms応答と、それに続く4x BadGatewayエラーで落ち着きます。永続ソケットを使用しない場合、この問題は解消されますが、すべての要求は500ミリ秒です。私が起こっていると思うのは、永続ソケットが各php-fpmプロセスをアイドリングから守り、それを拘束することです。そのため、次のプロセスは、何も残らなくなるまで選択され、エラーが発生すると、再起動されて次のラウンドで使用可能になります-ロビンループutソケットはプロセスで死にます。私はまだ「slowlog」をチェックしていませんが、nginxエラーログはこれをたくさん示しています:
* 188 recv()が失敗しました(104:ピアによって接続がリセットされました)アップストリームからの応答ヘッダーの読み取り中に、クライアント:...
Nginx/php-fpm/502の不正なゲートウェイの修正に関するインターネット上のすべての提案は、高負荷またはfcgi_passの設定ミスに関連しています。これはここでは当てはまりません。バッファ/サイズの増加、タイムアウトの変更、fcgi_passのunixソケットからtcpソケットへの切り替え、システムの接続制限の引き上げ....このようなことはここでは当てはまりません。
動的ではなくpm = ondemandを設定することで他の成功を収めましたが、アイドリング後に最初のfpm-processが強制終了されるとすぐに、後続のすべてのphp-fpmスポーンの永続ソケットがなくなります。 phpスクリプトでは、STREAM_CLIENT_PERSISTENTフラグを指定したstream_socket_client()を使用しています。 while/stream_select()ループはソケットデータを検出し、fread($ sock、4096)はデータを取得します。私は明らかにfclose()を呼び出しません。
リクエストの完了を超えてphp-fpmプロセスを拘束せずに永続ソケットを取得する方法について、追加の質問やアドバイスがある場合、または他の試みがあれば、私はそれをいただければ幸いです。
いくつかの便利なリンク:
Nginx + php-fpm "504 Gateway Time-out"エラー、負荷がほぼゼロ(テストサーバー上)
Nginx + PHP-FPM「エラー104接続がピアによってリセットされました」により、投稿が重複することがあります
http://www.linuxquestions.org/questions/programming-9/php-pfsockopen-552084/
https://stackoverflow.com/questions/14268018/concurrent-use-of-a-persistent-php-socket
http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/#Heading
https://stackoverflow.com/questions/242316/how-to-keep-a-php-stream-socket-alive
この問題をメーリングリストで報告しました。最終的にはphpのバグでしたが、現在はgitで解決されており、次のphpバージョンであるw00tに含まれているはずです。
誰かが興味を持っている場合: https://groups.google.com/forum/#!topic/highload-php-en/qGu3Eaifj9s