...

PHP-FPM プロセス管理を正しく設定する:pm.max_children などの説明

php-fpm のチューニング 同時に実行できる PHP-FPM プロセスの数、新しいプロセスの起動速度、およびリクエストの処理時間を決定します。その方法をご紹介します。 pm.max_children, 、pm、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers、pm.max_requests を設定して、負荷がかかったときにアプリケーションが素早く反応し、サーバーがスワッピングに陥らないようにします。.

中心点

  • pmモード: トラフィックに合わせてプロセスが適切に利用できるよう、static、dynamic、ondemand を正しく選択してください。.
  • pm.max_children:RAM 上の同時 PHP プロセスの数を、実際のプロセス消費量に合わせて調整する。.
  • 開始値/予備値: pm.start_servers、pm.min_spare_servers、pm.max_spare_servers を適切にバランスさせる。.
  • リサイクル: pm.max_requests を使用して、不要なオーバーヘッドを発生させることなくメモリリークを緩和します。.
  • モニタリング: ログ、ステータス、RAM を監視し、段階的に調整してください。.

プロセス管理が重要な理由

私は操縦します ピーエッチピーエフピーエム 各 PHP スクリプトは個別のプロセスとして実行され、並列リクエストはそれぞれ個別のワーカーを必要とします。適切な制限がない場合、リクエストはキューでブロックされ、 タイムアウト とエラーにつながります。上限を高く設定しすぎると、プロセスプールがメモリを消費し、カーネルが スワップする. このバランスは推測ゲームではありません。私は実際の測定値に基づいて判断し、安全マージンを確保しています。これにより、負荷が急変しても、レイテンシは低く抑えられ、スループットは安定します。.

私にとって重要なのは、明確な 目標値:RAMを使い切らずに、同時に何個のPHP実行を可能にしたい?同時に、ボトルネックがどちらにあるかもチェックするよ。 データベース, 、外部 API や Web サーバーにある場合。ボトルネックを把握して初めて、pm、pm.max_children などの適切な値を選択できます。私は保守的に開始し、測定してから段階的に増加させていきます。そうすることで、ハードリスタートや予期せぬ障害を回避できます。.

3つのpmモード:static、dynamic、ondemand

モード 静的 常に pm.max_children プロセスを正確に用意します。これにより、起動プロセスが不要になるため、非常に予測可能なレイテンシが得られます。負荷が非常に均一で、十分な RAM が利用可能な場合は、static を使用します。ただし、需要が変動する場合、static では少し無駄が生じます。 メモリ. そのため、私は静的(static)を、一定の実行が必要な場合に意図的に使用しています。.

と一緒に ダイナミック 私は開始量を起動し、プールサイズを min_spare と max_spare の間で変動させます。このモードは、トラフィックの波がある場合に適しています。なぜなら、ワーカーは必要に応じて生成され、終了するからです。私は、待ち時間なくピークに対応できるよう、常に十分なアイドルプロセスを確保しています。しかし、アイドルワーカーが多すぎると、不必要にリソースを消費してしまいます。 RAM, そのため、予備の余裕は狭く設定しています。そうすることで、プールは膨張することなく可動性を維持できます。.

モード オンデマンド 最初はワーカーが存在せず、PHP-FPM はリクエストがあったときにのみワーカーを起動します。これにより、アイドル時のメモリを節約できますが、最初のヒットには若干のレイテンシーがかかります。私は、呼び出し頻度の低いプール、管理ツール、または Cron エンドポイントには ondemand を選択しています。アクセス数の多いウェブサイトでは、ondemand は通常、応答時間が悪くなります。そのような場合は、明確に設定された予備値を持つ dynamic を明らかに優先します。.

pm.max_children を適切に設定する

私はそう思う pm.max_children PHP 用の利用可能な RAM とワーカーあたりの平均メモリから。まず、システム、Web サーバー、データベース、キャッシュ用にメモリを予約して、システムが アウトソーシング 実行中。残りの RAM を、実際に測定されたプロセス消費量で割ります。理論から、外れ値や負荷のピークを吸収するために 20~30 % の安全マージンを差し引きます。この結果を初期値として使用し、その後その効果を観察します。.

平均的なプロセス消費量は、次のようなツールを使って算出しています。 ps, 、top、または htop を使用して RSS/RES を確認します。重要:私は、アイドル状態ではなく、通常の負荷状態で測定しています。多くのプラグイン、フレームワーク、または大きなライブラリをロードすると、ワーカーあたりの消費量が顕著に増加します。さらに、CPU が曲線を制限します。プロセス数が多いと、 シングルスレッド-リクエストごとのCPUの性能が制限される。CPUの特性についてもっと詳しく知りたい方は、その背景について シングルスレッドパフォーマンス.

私は自分の仮定を透明にしています。PHP が実際に利用できる RAM の容量はどれくらいか? 典型的なリクエストにおけるワーカーのサイズは? どのようなピークが発生するか? 答えが合っていれば、pm.max_children を設定し、ソフトリロードを行い、RAM、応答時間、エラー率を確認します。その後、少しずつ上または下に調整していきます。.

サーバーサイズによる目安

次の表は、私に次のことを教えてくれます。 開始値 手元にあるものです。測定に取って代わるものではありませんが、最初の設定には確かな指針となります。私はアプリケーションごとに値を調整し、モニタリングで確認しています。予備容量が未使用のままの場合は、慎重に値を上げます。サーバーが RAM の限界に達した場合は、値を下げます。.

サーバーRAM PHP用RAM Ø MB/ワーカー pm.max_children (スタート) 用途
1~2 GB 約1 GB 50~60 15~20 小規模サイト、ブログ
4~8 GB ~4~6 GB 60~80 30~80 ビジネス、小規模店舗
16 GB以上 約10~12 GB 70~90 100~160 高負荷、API、ショップ

私は表を右から左に読みます:適合しますか? 用途 プロジェクトについて、PHP用にRAMが現実的に確保されているか確認するよ。それから、コードベースや拡張機能に合ったワーカーサイズを選ぶんだ。その後、pm.max_childrenを設定して、実稼働での効果を観察するよ。これらの手順をきちんと文書化すると、ヒット率と安定性が上がるんだ。.

スタート値、予備値、リクエスト値を設定する

と一緒に pm.start_servers すぐに利用可能なプロセスの数を決めます。低すぎると負荷がかかったときにコールドスタートが発生し、高すぎると不要な RAM を占有してしまいます。私はよく pm.max_children の 15~30 % を目安にして、負荷が比較的穏やかなスタートの場合は丸めます。 トラフィックのピーク時には、十分なワーカーが待機する前にリクエストが集中しないように、少し多めの起動数を選択します。この微調整により、最初の応答時間が大幅に短縮されます。.

価値観 pm.min_spare_servers および pm.max_spare_servers はアイドル期間を定義します。新しいリクエストが直接アクセスできるだけの空きワーカーを確保しますが、アイドルプロセスがメモリを無駄に消費しない程度に抑えます。ショップでは、ピークを平準化するために、より狭いウィンドウを設定することをお勧めします。 pm.max_requests メモリドリフトを抑えるために、数百回のリクエスト後にプロセスをリサイクルしています。目立たないアプリケーションの場合は 500~800 を選択し、リークが疑われる場合は意図的にそれより低い値に設定しています。.

モニタリングとトラブルシューティング

定期的にチェックしている 過去ログ, 、ステータスページ、RAM。pm.max_children の上限に達した警告は、上限を引き上げるか、コード/DB を最適化すべきという明確なシグナルです。502/504 エラーが頻繁に発生する場合は、Web サーバーのログとキューを確認します。 レイテンシーの著しい変動は、プロセス数が少なすぎる、I/O がブロックされている、またはプロセスコストが高すぎることを示しています。私はまず確かな事実を確認し、小さなステップで対応します。決して大きなジャンプはしません。.

ボトルネックは、 待ち時間 チェーン全体(Webサーバー、PHP-FPM、データベース、外部サービス)を測定します。特定のルートでのみバックエンド時間が長くなる場合は、プロファイリングによって原因を特定します。待ち時間が全体的に発生している場合は、サーバーとプールのサイズを調整します。 また、ワーカーのキューや D ステータスのプロセスを確認することも有用です。状況を把握してから初めて、制限を変更し、変更内容をすべて明確に文書化します。.

WebサーバーとPHP-FPMの連携

私は次のことを確認している。 ウェブサーバー-制限と PHP-FPM は調和しています。ワーカーが少なすぎる状態で Web サーバーに同時接続が多すぎると、キューやタイムアウトが発生します。ワーカーは設定されているものの、Web サーバーが受け入れを制限している場合、パフォーマンスは低下します。worker_connections、event-Loop、Keep-Alive などのパラメータは、PHP の負荷に直接影響します。実践的な微調整の入門として、以下のヒントが参考になります。 Webサーバーのスレッドプール.

私は保持します キープアライブ-タイムスロットを監視し、アイドル接続がワーカーを不必要にブロックしないようにします。静的アセットについては、PHP の前に積極的なキャッシュを設定し、プールからワークロードを遠ざけています。リバースプロキシキャッシュは、同一のレスポンスが頻繁に呼び出される場合にさらに役立ちます。これにより、pm.max_children を低く抑えながら、より高速な配信を実現できます。リクエストあたりの作業量を減らすことが、多くの場合、最も効果的な調整手段となります。.

php-fpm.conf の細かい調整

私は基本価値を超えて、それを調整します。 プールパラメータ いいですよ。 pm.max_spawn_rate 新しいワーカーの生成速度を制限して、負荷のピーク時にサーバーがプロセスを過度に開始して CPU スラッシュに陥るのを防ぎます。オンデマンドの場合、 pm.process_idle_timeout 未使用のワーカーがどれほど早く消えるか、つまり、開始オーバーヘッドが生じる時間が短すぎるか、RAM を占有する時間が長すぎるか、を決定します。 リスト-Socket では、Unix ソケットと TCP のどちらかを選択します。Unix ソケットはオーバーヘッドを削減し、 リストの所有者, listen.group そして listen.mode. どちらのバリエーションも、私は listen.backlog カーネルバッファにバーストが到達し、即座に拒否されないように、十分に高く設定してください。 rlimit_files 必要に応じて、ワーカーごとのオープンファイル数を増やして、同時アップロードやダウンロードが多いときに安定性を確保してるよ。優先順位が必要なときは、 process.priority, 、CPU 側で重要度の低いプールを多少後回しに処理するため。.

スローログとハングアップからの保護

粘り強いリクエストを可視化するために、私は スローログ.と一緒に リクエスト_スローログ_タイムアウト スタックトレースが スローログ と記述されます。これにより、ブロックする I/O、高価なループ、予期せぬロックなどを検出します。実際のハングアップに対しては、 リクエスト終了タイムアウト, リクエストの実行時間が長すぎる場合に、厳しく中断するものです。この時間枠は、 最大実行時間 PHPとウェブサーバーのタイムアウトを使って、あるレイヤーが他のレイヤーより早く切断されないようにします。実際には、保守的に開始し、負荷時のスローログを分析し、ログを溢れさせることなく、信号が意味のあるものになるまで段階的にしきい値を調整します。.

Opcache、memory_limit、およびワーカーのサイズへの影響

私は オプキャッシュ 私の RAM 計画に組み込みます。その共有メモリ領域は、ワーカーごとにカウントされるのではなく、すべてのプロセスで共有されます。サイズと断片化 (opcache.memory_consumption, interned_strings_buffer) はウォームアップ時間とヒット率に大きな影響を与えます。適切にサイズ設定された Opcache は、再コンパイルされるコードが少なくなるため、リクエストごとの CPU および RAM 負荷を軽減します。同時に、次の点にも注意してください。 メモリリミット: 高い値は、個別のケースではメモリ不足を防ぐことができますが、ワーカーあたりの理論上の最悪のケースの予算を増加させます。そのため、私は測定された平均値にバッファを加えた値で計画を立てており、単純な memory_limit を使用していません。プリロードや JIT などの機能はメモリ要件を増加させるため、私はそれらを意図的にテストし、pm.max_children の計算に追加消費量を組み込んでいます。.

プールを分離して優先順位付けする

アプリケーションを分割します 複数のプール 負荷プロファイルが大きく異なる場合。フロントエンドトラフィック用、管理/バックエンド用、Cron/アップロード用の3つのプールを用意し、ピークを分離して差別化された制限を設定しています。アクセス頻度の低いエンドポイントには、 オンデマンド フロントエンド用の短いアイドルタイムアウト ダイナミック 予備の余裕が少ない。 ユーザー/グループ および必要に応じて. chroot ソケット権限がどのウェブサーバープロセスがアクセスできるかを制御しながら、私はクリーンな分離を確保します。優先順位が必要な場合、フロントエンドはより多くの pm.max_children そして必要に応じて中立的な process.priority, 一方、Cron/レポートはより少ない予算と低い優先度で実行されます。これにより、バックグラウンドで重いジョブが実行されている場合でも、ユーザーインターフェースの応答性は維持されます。.

ステータスエンドポイントを適切に使用する

実行時間診断のために、私は pm.status_path およびオプション ping.path プールごとに。ステータスには、Active/Idle-Worker が表示されます。 リストキュー, 、スループット関連のカウンター、およびスローリクエストのメトリクス。リストキューが継続的に増加している場合や、アイドルワーカーが常に 0 の場合は、私にとって警報信号となります。運用上の詳細が外部に漏れないよう、これらのエンドポイントを認証と内部ネットワークで保護しています。さらに、以下を有効にしています。 catch_workers_output, 、再現が難しいエラーなど、ワーカーからのstdout/stderrを短期間で収集したい場合。これらのシグナルをシステムメトリクス(RAM、CPU、I/O)と組み合わせて、pm.max_children を増やすか、スペア値を更新するか、アプリケーションに手を加えるかを判断します。.

コンテナと VM の特徴

時点では コンテナ および小規模な VM では、cgroup の制限と OOM キラーの危険性に注意しています。pm.max_children は、 コンテナメモリ制限 また、ワーカーがシャットダウンされないよう、負荷のピークをテストします。コンテナではスワップがないため、安全マージンが特に重要になります。CPU クォータでは、利用可能な vCPU 数に合わせてワーカー数をスケーリングします。アプリケーションが CPU バウンドの場合、並列性を高めるとスループットよりもキューが発生しやすくなります。IO バウンドのワークロードは、RAM 予算が許す限り、より多くのプロセスに対応できます。さらに、私は 緊急再起動のしきい値 そして 緊急再起動間隔 マスタープロセスが、まれなバグによって短時間で複数の子プロセスがクラッシュした場合のクラッシュスパイラルを吸収します。これにより、原因を分析している間もサービスは利用可能なままとなります。.

ダウンタイムのないスムーズなデプロイとリロード

私は次のことを計画している。 リロード 進行中のリクエストが確実に完了するように。 優雅なリロード (たとえば、systemd reload を使って)新しい設定を、開いている接続を強制終了せずに適用するんだ。Web サーバーが接続の切断を認識しないように、ソケットのパスは安定させておくよ。Opcache を無効にするバージョン変更があるときは、デプロイ直後のレイテンシーのピークを抑えるために、キャッシュをウォームアップ(プリロード/ウォームアップリクエスト)するんだ。 大きな変更は、まず小規模なプールまたは同一設定のカナリアインスタンスでテストしてから、広く展開します。すべての調整は、タイムスタンプとメトリックのスクリーンショットとともに変更ログに記録されます。これにより、予期せぬ副作用が発生した場合のトラブルシューティングの時間を短縮できます。.

バースト動作とキュー

負荷のピークは、調整された 待ち行列のデザイン から。私は listen.backlog カーネルが短期間でより多くの接続試行をバッファリングできるほど高い値に設定します。Web サーバー側では、プールごとの同時 FastCGI 接続の最大数を、 pm.max_children 適合します。これにより、バーストは PHP の奥深く(コスト高)よりも、Web サーバーで短時間(コスト低)に蓄積されるようになります。私は リストキュー FPM ステータス:定期的に上昇する場合は、ワーカー数を増やすか、キャッシュヒット率を最適化するか、アグレッシブなキープアライブ値を下げます。目標は、ピーク時に タイム・ツー・ファースト・バイト リクエストを無限のキューで放置するのではなく、安定性を維持すること。.

調整のための実践的なワークフロー

私はまず 監査:RAM 予算、プロセスサイズ、I/O プロファイル。その後、pm.max_children および pm モードの保守的な開始値を設定します。次に、負荷テストを実行するか、実際のピーク時間を観察します。すべての変更と、メトリックおよび時間枠をログに記録します。調整のたびに、RAM、レイテンシ P50/P95、およびエラー率を確認してから、次のステップに進みます。.

限界に繰り返し直面しても、すぐにはエスカレートしません。 労働者-数。まず、クエリ、キャッシュヒット率、および高価な機能を最適化します。IO負荷の高い作業をキューに移し、応答経路を短縮します。アプリケーションが効率的に動作してから初めて、プールサイズを拡大します。この手順により、リソースを節約し、他の場所での二次的な損害を回避できます。.

典型的なシナリオ:例値

2 GB の vServer で、私は約 1 GB PHP-FPM 用に、ワーカーの消費量を約 50~60 MB に設定します。これにより、pm.max_children を 15~20 で開始し、小さな開始量で dynamic を使用します。min_spare は 2~3、max_spare は 5~6 に設定します。pm.max_requests は、プロセスが定期的に交換されるように 500 に設定します。 これらの設定により、小規模なプロジェクトで安定した応答時間が得られます。.

8 GB の RAM では、通常 4~6 GB を ピーエッチピーエス そして、ワーカーサイズを 60~80 MB に設定します。これにより、30~80 の子プロセスが起動範囲となります。 pm.start_servers は 15~20、min_spare は 10~15、max_spare は 25~30 に設定します。pm.max_requests は 500~800 の間で選択します。負荷がかかった状態で、RAM のピークに余裕があるかどうかを確認し、慎重に増加させます。.

16 GB 以上の RAM を搭載した高負荷のセットアップでは、10~12 GB を FPM. ワーカーあたり70~90 MBの場合、100~160のプロセスにすぐ到達します。静的か動的かが適切かは、負荷の形態によって異なります。持続的に高い負荷の場合は静的、波状的な需要の場合は動的が適しています。いずれの場合も、一貫したモニタリングは必須です。.

障害を回避し、優先順位を設定する

私は数字を間違えることはありません。 来場者 同時実行される PHP スクリプトの数。多くのページアクセスはキャッシュにヒットし、静的ファイルを提供するか、PHP 以外でブロックされます。そのため、pm.max_children は、セッション数ではなく、測定された PHP 時間でサイズを決定しています。プロセスが控えめに設定されていると、待機中のリクエストが発生し、エラー率が高くなります。値が高すぎると、メモリがスワップに振り分けられ、すべての処理が遅くなります。.

よくある誤解:プロセスが増えれば、より多くの成果が得られる スピード. 実際には、CPU、IO、RAM のバランスが重要です。CPU が 100 % に達し、レイテンシが急上昇した場合、ワーカーを追加してもほとんど効果はありません。真のボトルネックを解消するか、キャッシュによって負荷を軽減するほうが効果的です。ワーカーがボトルネックになることが多い理由については、ガイドブックで説明しています。 PHPワーカーのボトルネック.

簡単にまとめると

まず、実際の RAM-ワーカーあたりの消費量を計算し、そこからバッファ付き pm.max_children を設定します。次に、負荷形態に合わせて pm モードを選択し、開始値と予備値のバランスを調整します。 pm.max_requests を使用して、不必要なオーバーヘッドなしにプロセスを最新の状態に保ちます。ログ、ステータス、メトリクスは、すべての変更を測定可能にするために、クリーンなモニタリングに転送します。これにより、短い応答時間、安定したプール、およびピーク時の予備力を持つサーバー負荷を実現しています。.

現在の記事