以下の設定において、どのように動くかを説明します。
pm=dynamic pm.start_servers=2 pm.min_spare_servers=4 pm.max_spare_servers=8 pm.max_children=10 pm.max_requests=0
一気に50リクエストがやってきたと仮定する
その後30分はリクエストが一切なかったと仮定します。 なお、ベースはGeminiです。
- 初期状態,2 → 4,起動時は start_servers の 2人だけど、min_spare_servers が 4人だから、すぐに4人まで補充される
- 50リクエスト到来,10,一気に50人もお客さまが!でもお店のキャパ(max_children)は 10人まで。フル稼働で10人が働く
- 処理中,10,10人で50リクエストを回すから、40リクエストは「行列(キュー)」で待たされる
- 全処理終了直後,10,50件を捌き終わって、10人の職人が全員「手が空いた(Idle)」状態になる
- 調整(数秒後),8,「暇な職人は最大8人まで(max_spare_servers=8)」というルールがあるから、溢れた2人はお休み(終了)して 8人になる
- 30分間の沈黙,8,その後リクエストがなくても、min_spare_servers(4) 以上 max_spare_servers(8) 以下なら、そのまま 8人で待機し続ける
要点
- 一気にアクセスがやってくると、max_childrenまでプロセス数は増える可能性がある
- アクセスが落ち着くと、max_spare_serversまで常時待機のプロセス数は減らされる
- 一度max_spare_serversまでプロセス数が増えると、その後プロセス数が減るのは各プロセスがmax_requests(ただし0だと無制限)回捌いたタイミングである。
あとがき
- php-fpmの子プロセスが消費する可能性のあるメモリサイズを勘案して、pm.max_spare_serversと pm.max_childrenを決定する必要がある点が重要です。
- 仮にLaravelだと1プロセスあたり100M超えになる可能性もあり、採用しているフレームワークを勘案したり、「推測するな計測せよ」での調整を推奨します。