PHP ハンドラー? mod_php? FPM?コード行以外の PHP の内部動作を理解するにはどうすればよいでしょうか?サーバー上で PHP を実行して Web アプリケーションを迅速に構築できることはわかっていますが、最大規模に達するために環境と構成を最適化するにはどうすればよいでしょうか? PHP には非同期またはイベント駆動ではないという欠点があることはわかっていますが、だからこそ最大限の最適化を確保する必要があります。サーバー環境が PHP アプリケーションのパフォーマンスに与える影響は、許容できる以上に大きくなる可能性があります。 PHP エコシステムを注意深く検査すると、簡単に解決できる領域でのパフォーマンスの低下を避けることができます。
PHP は、エコシステムとして、無数の設定でデプロイできます。 Web アプリケーションのパフォーマンスとスケーラビリティに対する要求が時間の経過とともに増加するにつれて、PHP コードの呼び出し、解釈、処理の方法も増加しています。この構成の最適化の進化により、スケール、セキュリティ、耐久性の向上が可能になります。環境のセットアップ方法が不明な場合は、環境を監査し、古いアーキテクチャ上の決定を再検討する時期が来ている可能性があります。速度と信頼性を高めるために PHP アプリケーションを最適化することは、コードだけではありません。 PHP 処理の最新テクノロジーを活用すると、これまで気づかなかった問題点の多くが解決される可能性があります。 Web サーバーと連動するように PHP を構成するさまざまな方法を検討し、パフォーマンスとスケーラビリティの観点からこれらのランタイムを比較します。
すべての PHP アプリケーションの内部には、Web サーバーと PHP インタープリターが存在します。 HTTP トラフィックが受信されると、Web サーバーは静的データ (画像、JavaScript、CSS など) または動的データのいずれかを提供してリクエストを完了します。 Web サーバーはリクエストを PHP に渡してアプリケーション コードの解釈を処理し、応答を作成して Web サーバーに返し、その後顧客に返します。このプロセス中に、Web サーバーが PHP ランタイムと通信するインターフェイスは、PHP ハンドラーと呼ばれます。
実行しているハンドラーを確認する簡単な方法は、サーバー上に phpinfo.php という名前のダミー ファイルを作成し、次のコードに配置することです:
<?php phpinfo(); ?><br>
そのページをブラウザにロードし、サーバー API エントリ ブロックを探します。
mod_cgi は、現在でも一般的なオプションであり、主に共有ホスティング環境や、ほぼ 10 年間アップグレードされていない (非常に) レガシー アプリケーションで使用されます。これは古くて時代遅れなので、最新の PHP 環境では決して使用しないことをお勧めします。
このメソッドを使用して PHP コードを実行すると、Apache プロセスの外側に新しい CGI プロセスが作成され、リクエストごとに PHP インタープリターがロード (および構成の読み取り) されます。 このアプローチは必ずしも最も効率的または効果的であるとは限りません。 おそらく、この方法の方が安全です。suEXEC mod_cgi を使用すると、PHP コードの実行を Apache の範囲外に保つことができます。つまり、欠陥のあるコードや悪意のあるコードが解釈の範囲外に出ることができなくなります。この方法は、同じ PHP インタープリターの下にある共有ホスティング環境で一般的です。
残念ながら、この方法では悪い点が良い点を上回ります。非効率的でパフォーマンスが低く、サーバー リソースへの負担が大きいため、すぐに本格的な PHP 開発者からは好まれなくなりました。また、PHP オペコード キャッシュ メソッドもサポートしていないため、深刻な高トラフィック環境では明らかに除外されます。
CGI と同様に、suPHP (シングル ユーザー PHP) は Apache モジュールです。どのユーザーがどのプロセスを実行していて CPU に負担をかけているかを確認できるという利点があります。ただし、CGI と同様に、これは非効率的であり、トラフィックが増加し始めると、すぐにサーバーが限界に達してしまいます。 suPHP の利点は本質的にセキュリティであり、PHP スクリプトは所有者ユーザーとして実行されるため、単一サーバー上で複数の PHP アプリケーションをホストするための一般的なオプションです。したがって、アプリケーションがアップロード フォームを提供する場合、アップロードされたファイルは、必要な権限がそのまま残った状態で、PHP スクリプト自体の同じ所有者によって所有されます。これにより、所有者以外のユーザーによる PHP スクリプトの実行も保証されません。
suPHP を使用すると、リクエストごとに個別のプロセスとして PHP を実行し、トラフィックが急増し始めるとすぐにリソースを最大限に活用できます。 CGI と同様に、mod_suphp は高トラフィックのシナリオではすぐに人気がなくなりました。残念ながら、suPHP はオペコード キャッシュのサポートも提供していなかったため、すぐに人気が落ちました。また、最後のリリースが 2013 年であることを考慮すると、このプロジェクトはサポートされなくなったと考えるのが安全かもしれません。
PHP ハンドラーの事実上の標準と考えられている mod_php は、その速度とスケールによりすぐに人気が高まりました。おそらくすでに mod_php がインストールされているかもしれません。 phpinfo() ダンプでは、サーバー API ブロックの下に Apache 2.0 ハンドラーが表示されます。
DSO ハンドラーは、おそらく利用可能な中で最も古く、最速のハンドラーの 1 つです。 mod_php モジュールは、Apache プロセス自体の一部として PHP を統合し、Apache が PHP コードを解釈できるようにします。したがって、リクエストごとに新しい PHP プロセスを生成することはなく、PHP が Apache 子プロセスとしてプリロードされるため、オーバーヘッドが低くなります。
mod_php の最大の利点の 1 つは、オペコード キャッシュ (APC など) を利用できることです。これにより、平均応答時間が非常に大幅に短縮されます。 APC についてまだチェックしていない方は、オペコード キャッシュについて簡単に説明した別の投稿を用意しています。また、私の同僚の Rob Bolton がそれについて詳しく説明した優れた記事を作成しています。
mod_php の欠点は、すべての PHP アプリケーション ファイルが Apache ユーザーによって所有され、実行されることです。これにより、どの特定のユーザーがサーバー リソースに影響を与えているかをある程度把握できなくなります。最近の PHP アプリケーションにとって、これは深刻な問題ではないと思います。おそらく、単一サーバー上で複数の Web サイトを実行しているのではなく、サーバー ファーム全体で 1 つの巨大な PHP アプリケーションを実行していることでしょう。
FastCGI はその名前が示すとおり、パフォーマンスを念頭に置いて構築された CGI モジュールとしての高速 PHP 実装ハンドラーです。 FastCGI は (mod_php とは異なり) Web サーバーを 1 つだけに制限せず、PHP スクリプトをメモリ内に保持し、リクエストごとに新しい PHP プロセスを呼び出す必要がないため、CPU オーバーヘッドが軽減されます。 Apache ユーザーではなく所有ユーザーとして PHP スクリプトを実行できる利点があるため、セキュリティも厳重です。
FastCGI の主な欠点は、メモリ消費に負担がかかることです (ただし、mod_php ほどではありません)。 PHP スクリプトをメモリ内に保持すると、サーバー上の RAM の使用量が急増し始める場合があります。これは、APC や Memcached などのメモリ内キャッシュ メカニズムでよく見られる症状です。ただし、メモリ内にデータを保持すると、CPU 使用率が低下し、そのデータへのアクセスが高速化され、リクエストの全体的な応答時間が短縮されることになるため、適切なトレードオフを見つける必要があります。
速度を犠牲にすることなく、共有環境内でセキュリティが主な懸念事項である場合、FastCGI は suPHP に代わる優れた最新の代替手段です。
技術的にはそれ自体はハンドラーではありませんが、php-fpm はより効率的なプロセス管理のために FastCGI と結合されており、FastCGI と互換性のある任意のサーバーで使用できます。 FPM (FastCGI Process Manager) は、ワーカー FastCGI プロセスを処理するために spawn-fcgi を使用した経験がある人にとって適切な代替品です。 FPM は、サーバー API (PHP と Apache 間のインターフェイス) である FastCGI SAPI を管理します。余談ですが、コマンドライン実行の場合、PHP-CLI は PHP 用の SAPI です。
FPM はオペコード キャッシュもサポートしており、すべての php-fpm ワーカー間で APC キャッシュを共有できます。 php-fpm が提供する追加機能により、高トラフィックの PHP 環境がこれまで想像もできなかったレベルでスケールし始めることが可能になります。この種の技術的利点により、スケールの拡大、ハードウェアと OS リソースの有効活用、よりスマートなプロセス管理、同時実行性とスループットの向上が可能になりました。 PHP アプリケーションは、複数のサーバー間でより適切に拡張することもできます。 PHP 5.3.3 以降、FPM は PHP に同梱されるようになりました。
ハンドラーについてたくさん話してきましたが、最適な環境に到達するには、PHP アプリケーションで達成しようとしているスケールのレベルに合わせて、ハンドラーを適切な Web サーバーと組み合わせる必要があります。 PHP アプリケーションで最も人気のある 2 つの Web サーバーは、Apache と Nginx です。各サーバーは独自のテクノロジーで動作しており、長所と短所がありますが、Nginx + php-fpm は、速度とスケールをめぐる戦いにおいて明らかな競争相手となっています。
世界で最も一般的な Web サーバーである Apache にも制限があります。ユーザー トラフィックが流入すると、Apache はリクエストごとに新しいワーカー プロセスを生成します。プリフォーク モードと MPM モードはどちらもクライアント接続ごとに新しいプロセスを作成しますが、ワーカー モードはプロセスごとに複数の接続を処理しながら、より多くのリクエストを処理できます。それにもかかわらず、トラフィックが増加し始めると、接続が RAM を使用し、CPU をめぐって競合するため、メモリが使い果たされ始めることに気づくでしょう。トラフィックの多い環境を実行すると、接続プールがすぐに最大になってしまうことに気づきます。ハードウェア リソースを考慮して最大プロセス数と同時接続数を最適化するように Apache を構成できますが、依然としてプロセスが競合しており、トラフィックが増加するにつれて拡張する必要性も高まります。
Nginx には、イベント駆動型、ノンブロッキング、非同期のアーキテクチャ モデルが含まれています。 Node.js が私たちに何かを教えてくれたとすれば、この設計は複数のリクエストを同時に処理するのに役立つ完璧な環境を作成します。ノンブロッキングであるため、待機することなく追加のイベント (ユーザー接続) を処理し続けることができ、非同期であるため、複数の同時ユーザーを同時に処理できます。このモデルの美しさにより、Nginx が同じサーバー設定下で大量のトラフィックを処理する有力な候補であることがすぐに証明されました。 Nginx を使用すると、プロセスをクラスター化してマシン上のコアごとに追加のプロセスを生成することもできるため、サーバーごとにより多くのリクエストを処理する能力が向上します。
明らかに、選択肢があります。主な関心事がセキュリティであるか速度であるかに関係なく、PHP アプリケーションをデプロイするエコシステムの構築に進む前に、アーキテクチャを深く検討する必要があります。アプリケーションのサイズとトラフィックが増大しても拡張性を維持するには、当面のニーズだけでなく将来のニーズも考慮してください。
高トラフィック環境では、Nginx のイベント駆動型アーキテクチャ モデルを php-fpm と組み合わせることで、大量のトラフィックを処理するように最適化された PHP を実行することになります。もちろん、コード自体を最適化して平均応答時間を短縮する方法は他にもありますが、ホスティングの観点から見ると、Nginx と php-fpm を使用すれば、安心してスムーズに作業を進めることができます。
翻訳:https://blog.appdynamics.com/php/get-handle-php-handlers