前書き
多くの先輩方が、リロードによってプロセス全体のスムーズさを確保できると警告しています。いわゆるスムーズとは、リロード プロセス中に、現在のリクエストを処理する前に古いプロセスが早期に終了しないことを意味します。私は長年、この記述に疑問を抱いたことはありませんでしたが、ある日、リロードしたときに 502 エラーが発生し、考え直さなければならなくなりました。
問題を再現するにはどうすればよいですか?シミュレートする簡単なスクリプトを作成してみましょう:
<?php sleep(11); echo "foo"; ?>
この時点で、ブラウザを使用してこの URL を参照し、すぐにリロード操作を実行すると、502 エラーが表示されます。
PHPはそんなに弱いですか?リロードの基本的なスムーズささえ保証できないのでしょうか?答えはもちろんノーです。実際、私たちの目標は
process_control_timeout
パラメータを通じて達成できます。残念ながら、このパラメータのデフォルトは 0 です。つまり、この記事では 10 秒に設定しています。前の実験手順を再実行すると、今度は結果が正常に出力されます。ただし、さらにいくつか実験してみると、リロード時にスリープがすぐに終了することがわかります。これは、リロードからのシグナルを受信した後にスリープが直接戻るためです。
<?php sleep(11); echo "foo"; sleep(11); echo "bar"; ?>
再実行してみましょう。前の実験手順を実行すると、502 エラーが再び表示されることがわかります。これは、リロードにより最初のスリープはすぐに終了しますが、2 番目のスリープはまだ有効であり、
process_control_timeoutの制限時間を超えているためです。
process_control_timeoutを 12 秒に設定すると、再び良好になります。
このように、
process_control_timeoutに適切な値を設定するだけでリロード操作がスムーズになりますが、適切な値とは何でしょうか?小さすぎると効果が得られない可能性がありますが、大きすぎると副作用はありますか?質問を含めて前回の実験を繰り返しますが、今回は別のモニタリングを追加します:
shell> watch -n1 'ps aux | grep php[-]fpm'
このモニタリングの目的は、リロード プロセス中の PHP-FPM プロセス数の変化を観察することです。効果をより明確にする PHP-FPM の起動モードを静的モードに変更し、同時にプロセス数が多すぎないようにすることをお勧めします。
最後の実験を繰り返したところ、リクエストを実行していたプロセスを除いて、他のプロセスが直接強制終了され、新しいプロセスがすぐに開始されず、最後の古いプロセスが実行され、新しいプロセスが実行されるまでスタックしていることがわかりました。プロセスが実行されました。起動プロセスを完了するだけです。この間に他のリクエストが来た場合、すぐには対応できないことは間違いありません。
私たちの実験に基づいて、デフォルトでは、PHP-FPM はリロード操作のスムーズな実行を保証できないと結論付けることができます。同時に、その値を設定することはできないことに注意してください。大きすぎると、システムでより深刻なリクエストの輻輳の問題が発生する可能性があります。
概要
上記は PHP のリロード操作に関するものです。さらに関連するコンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。