序章

ApacheとNginxは、世界で最も一般的な2つのオープンソースWebサーバーです。 一緒に、彼らはインターネット上で50% of以上のトラフィックを提供する責任があります。 どちらのソリューションも、さまざまなワークロードを処理し、他のソフトウェアと連携して完全なWebスタックを提供することができます。

ApacheとNginxは多くの性質を共有していますが、完全に互換性があると考えるべきではありません。 それぞれが独自の方法で優れており、この記事ではそれぞれの長所と短所について説明します。

総括

ApacheとNginxの違いに飛び込む前に、これら2つのプロジェクトの背景とそれらの一般的な特徴を簡単に見てみましょう。

Apache

Apache HTTPサーバーは、1995年にRobert McCoolによって作成され、1999年からApacheSoftwareFoundationの指導の下で開発されました。 HTTP Webサーバーは財団の元のプロジェクトであり、最も人気のあるソフトウェアであるため、単に「Apache」と呼ばれることがよくあります。

Apache Webサーバーは、少なくとも1996年から2016年まで、インターネット上で最も人気のあるサーバーでした。 この人気のため、Apacheは他のソフトウェアプロジェクトからの優れたドキュメントと統合サポートの恩恵を受けています。

Apacheは、その柔軟性、パワー、およびほぼユニバーサルなサポートのために、管理者によって選択されることがよくあります。 動的にロード可能なモジュールシステムを介して拡張可能であり、追加のソフトウェアを必要とせずに、PHPなどの多くのスクリプト言語に直接サービスを提供できます。

Nginx

2002年、Igor Sysoevは、C10K問題への回答としてNginxの作業を開始しました。これは、Webサーバーが1万の同時接続を処理できるようにするための未解決の課題でした。 Nginxは2004年に公開され、非同期のイベント駆動型アーキテクチャに依存することでこの目標を達成しました。

Nginxは、その軽量なフットプリントと最小限のハードウェアで簡単に拡張できる機能により、人気がApacheを上回りました。 Nginxは静的コンテンツの迅速な提供に優れており、独自の堅牢なモジュールシステムを備えており、必要に応じて動的リクエストを他のソフトウェアにプロキシできます。

Nginxは、リソースの効率と負荷時の応答性、および単純な構成構文のために、管理者によって選択されることがよくあります。

接続処理アーキテクチャ

ApacheとNginxの違いの1つは、接続とネットワークトラフィックを処理する特定の方法です。 これはおそらく、負荷がかかった状態での応答方法における最も重要な違いです。

Apache

Apacheは、クライアント要求の処理方法を指示するさまざまなマルチプロセッシングモジュール(ApacheはこれらのMPMと呼びます)を提供します。 これにより、管理者は接続処理アーキテクチャを構成できます。 これらは:

  • mpm_prefork :この処理モジュールは、リクエストを処理するために、それぞれ1つのスレッドでプロセスを生成します。 各子は、一度に1つの接続を処理できます。 リクエストの数がプロセスの数よりも少ない限り、このMPMは非常に高速です。 ただし、リクエストがプロセスの数を超えるとパフォーマンスが急速に低下するため、多くのシナリオでこれは適切な選択ではありません。 各プロセスはRAM消費に大きな影響を与えるため、このMPMを効果的に拡張することは困難です。 スレッドを念頭に置いて構築されていない他のコンポーネントと組み合わせて使用する場合でも、これは依然として良い選択かもしれません。 たとえば、PHPは常にスレッドセーフであるとは限らないため、このMPMは、これらのファイルを処理するためのApacheモジュールであるmod_phpを安全に操作する方法として推奨されています。

  • mpm_worker :このモジュールは、それぞれが複数のスレッドを管理できるプロセスを生成します。 これらの各スレッドは、単一の接続を処理できます。 スレッドはプロセスよりもはるかに効率的です。つまり、このMPMはプリフォークMPMよりも拡張性が高くなります。 プロセスよりもスレッドの数が多いため、これは、新しい接続が、空きプロセスを待たずに、すぐに空きスレッドを取得できることも意味します。

  • mpm_event :このモジュールは、ほとんどの状況でワーカーモジュールに似ていますが、キープアライブ接続を処理するように最適化されています。 ワーカーMPMを使用する場合、接続が有効である限り、要求がアクティブに行われているかどうかに関係なく、接続はスレッドを保持します。 イベントMPMは、キープアライブ接続を処理するための専用スレッドを確保し、アクティブな要求を他のスレッドに渡すことによって、キープアライブ接続を処理します。 これにより、モジュールがキープアライブ要求によって停止するのを防ぎ、より高速な実行を可能にします。

Apacheは、さまざまな接続および要求処理アルゴリズムを選択するための柔軟なアーキテクチャを提供します。 提供される選択肢は、主にサーバーの進化と、インターネット環境の変化に伴う同時実行の必要性の高まりによるものです。

Nginx

Nginxは、Apacheの後に登場し、サイトが大規模に直面する並行性の問題をより認識しました。 その結果、Nginxは、非同期の非ブロッキングイベント駆動型接続処理アルゴリズムを使用するようにゼロから設計されました。

Nginxはワーカープロセスを生成し、各プロセスは数千の接続を処理できます。 ワーカープロセスは、イベントを継続的にチェックして処理する高速ループメカニズムを実装することにより、これを実現します。 実際の作業を接続から切り離すことで、新しいイベントがトリガーされた場合にのみ、各ワーカーが接続に関心を持つことができます。

ワーカーによって処理される各接続は、イベントループ内に配置されます。 ループ内では、イベントは非同期で処理されるため、作業を非ブロッキング方式で処理できます。 接続が閉じると、ループから削除されます。

このスタイルの接続処理により、Nginxは限られたリソースで拡張できます。 サーバーはシングルスレッドであり、新しい接続を処理するためにプロセスが生成されないため、負荷が高い場合でも、メモリとCPUの使用率は比較的一定に保たれる傾向があります。

静的コンテンツと動的コンテンツ

実際のユースケースに関して、ApacheとNginxの最も一般的な比較の1つは、各サーバーが静的および動的コンテンツの要求を処理する方法です。

Apache

Apacheサーバーは、従来のファイルベースの方法を使用して静的コンテンツを処理できます。 これらの操作のパフォーマンスは、主に上記のMPMメソッドの関数です。

Apacheは、問題の言語のプロセッサを各ワーカーインスタンスに埋め込むことにより、動的コンテンツを処理することもできます。 これにより、外部コンポーネントに依存することなく、Webサーバー自体の中で動的コンテンツを実行できます。 これらの動的プロセッサは、動的にロード可能なモジュールを使用して有効にすることができます。

動的コンテンツを内部で処理するApacheの機能は、LAMPの人気に直接貢献しました( L inux- A pache- M ySQL- P [X157X ] HP)アーキテクチャ。PHPコードはWebサーバー自体によってネイティブに実行できるため。

Nginx

Nginxには、動的コンテンツをネイティブに処理する機能はありません。 PHPやその他の動的コンテンツのリクエストを処理するには、Nginxはリクエストを外部ライブラリに渡して実行し、出力が返されるのを待つ必要があります。 その後、結果をクライアントに中継できます。

これらのリクエストは、Nginxが話す方法を知っているプロトコルの1つ(http、FastCGI、SCGI、uWSGI、memcache)を使用して、Nginxと外部ライブラリによって交換される必要があります。 実際には、FastCGI実装である PHP-FPM は通常、ドロップインソリューションですが、Nginxは実際には特定の言語とそれほど密接に結合されていません。

ただし、この方法にはいくつかの利点もあります。 動的インタープリターはワーカープロセスに組み込まれていないため、そのオーバーヘッドは動的コンテンツに対してのみ存在します。 静的コンテンツは簡単な方法で提供でき、通訳者は必要な場合にのみ連絡されます。

分散構成と集中構成

ApacheとNginxは、ディレクトリごとにオーバーライドを許可するアプローチが大きく異なります。

Apache

Apacheには、コンテンツディレクトリ自体の隠しファイル内のディレクティブを検査および解釈することにより、ディレクトリごとに追加の構成を許可するオプションが含まれています。 これらのファイルは、.htaccessファイルと呼ばれます。

これらのファイルはコンテンツディレクトリ自体に存在するため、リクエストを処理するときに、Apacheはリクエストされたファイルへのパスの各コンポーネントで.htaccessファイルをチェックし、その中にあるディレクティブを適用します。 これにより、Webサーバーの分散構成が効果的に可能になります。これは、URLの書き換え、アクセス制限、承認と認証、さらにはキャッシュポリシーの実装によく使用されます。

上記の例はすべてメインのApache構成ファイルで構成できますが、.htaccessファイルにはいくつかの重要な利点があります。 まず、これらはリクエストパスに沿って検出されるたびに解釈されるため、サーバーをリロードせずにすぐに実装されます。 次に、非特権ユーザーが構成ファイル全体を制御することなく、自分のWebコンテンツの特定の側面を制御できるようにします。

これにより、コンテンツ管理システムなどの特定のWebソフトウェアが、中央構成ファイルへのアクセスを提供せずに環境を構成するための簡単な方法が提供されます。 これは、共有ホスティングプロバイダーによっても使用され、クライアントが特定のディレクトリを制御できるようにしながら、メイン構成の制御を維持します。

Nginx

Nginxは、.htaccessファイルを解釈せず、メイン構成ファイルの外部でディレクトリごとの構成を評価するためのメカニズムも提供しません。 Apacheは元々、単一のサーバー上で多くの異種Webデプロイメントを並べて実行することが有利であり、権限を委任することが理にかなっているときに開発されました。 Nginxは、個々のデプロイメントがコンテナー化され、独自のネットワーク構成で出荷される可能性が高く、この必要性を最小限に抑えたときに開発されました。 これは、状況によってはApacheモデルよりも柔軟性が低い場合がありますが、独自の利点があります。

ディレクトリレベルの構成の.htaccessシステムに対する最も顕著な改善は、パフォーマンスの向上です。 任意のディレクトリで.htaccessを許可する可能性のある一般的なApacheセットアップの場合、サーバーは、要求ごとに、要求されたファイルに至るまでの各親ディレクトリでこれらのファイルをチェックします。 この検索中に1つ以上の.htaccessファイルが見つかった場合は、それらを読み取って解釈する必要があります。 ディレクトリオーバーライドを許可しないことにより、Nginxは、リクエストごとに1つのディレクトリルックアップとファイル読み取りを実行することで、リクエストをより高速に処理できます(ファイルが従来のディレクトリ構造にあると想定)。

もう1つの利点は、セキュリティ関連です。 ディレクトリレベルの構成アクセスを配布すると、セキュリティの責任が個々のユーザーに分散されます。個々のユーザーは、このタスクを適切に処理することを信頼されていない可能性があります。 これらの懸念があなたの心に響く場合は、Apacheで.htaccessの解釈をオフにすることが可能であることに注意してください。

ファイルとURIベースの解釈

Webサーバーが要求を解釈し、それらをシステム上の実際のリソースにマップする方法は、これら2つのサーバーが異なるもう1つの領域です。

Apache

Apacheは、リクエストをファイルシステム上の物理リソースとして、またはより抽象的な評価が必要なURIの場所として解釈する機能を提供します。 一般に、前者の場合、Apacheは<Directory>または<Files>ブロックを使用しますが、より抽象的なリソースには<Location>ブロックを使用します。

ApacheはゼロからWebサーバーとして設計されているため、デフォルトでは通常、要求をファイルシステムリソースとして解釈します。 まず、ドキュメントのルートを取得し、ホストとポート番号の後にリクエストの一部を追加して、実際のファイルを見つけようとします。 基本的に、ファイルシステム階層はWeb上で利用可能なドキュメントツリーとして表されます。

Apacheは、リクエストが基盤となるファイルシステムと一致しない場合の代替手段をいくつか提供します。 たとえば、Aliasディレクティブを使用して、別の場所にマップできます。 <Location>ブロックの使用は、ファイルシステムではなくURI自体を操作する方法です。 ファイルシステム全体に構成をより柔軟に適用するために使用できる正規表現のバリアントもあります。

Apacheには、基盤となるファイルシステムと他のWeb URIの両方を操作する機能がありますが、ファイルシステムメソッドに大きく依存しています。 これは、ディレクトリごとの構成に.htaccessファイルを使用するなど、いくつかの設計上の決定に見られます。 Apache docs 自体は、リクエストが基盤となるファイルシステムをミラーリングしている場合に、URIベースのブロックを使用してアクセスを制限しないように警告しています。

Nginx

Nginxは、Webサーバーとプロキシサーバーの両方として作成されました。 これら2つの役割に必要なアーキテクチャにより、主にURIで機能し、必要に応じてファイルシステムに変換されます。

これは、Nginx構成ファイルが構築および解釈される方法から明らかです。 Nginxは、ファイルシステムディレクトリの構成を指定するメカニズムを提供せず、代わりにURI自体を解析します。

たとえば、Nginxのプライマリ構成ブロックはserverおよびlocationブロックです。 serverブロックは要求されているホストを解釈し、locationブロックはホストとポートの後に続くURIの部分を照合する役割を果たします。 この時点で、リクエストはファイルシステム上の場所としてではなく、URIとして解釈されています。

静的ファイルの場合、すべての要求は最終的にファイルシステム上の場所にマップする必要があります。 まず、Nginxはリクエストを処理するサーバーとロケーションのブロックを選択し、次にドキュメントルートをURIと組み合わせて、指定された構成に従って必要なものをすべて適応させます。

これは似ているように見えるかもしれませんが、リクエストをファイルシステムの場所ではなく主にURIとして解析することで、Nginxはウェブ、メール、プロキシサーバーの両方の役割でより簡単に機能できるようになります。 Nginxは、さまざまなリクエストパターンに応答する方法をレイアウトすることで構成されます。 Nginxは、リクエストを処理する準備ができるまでファイルシステムをチェックしません。これは、.htaccessファイルの形式を実装しない理由を説明しています。

ApacheとNginxを一緒に使用する

ApacheとNginxの両方の利点と制限を確認した後、どちらのサーバーがニーズに適しているかをよりよく理解できる場合があります。 場合によっては、各サーバーの長所を組み合わせて活用することが可能です。

このパートナーシップの従来の構成では、NginxをリバースプロキシとしてApacheの前に配置します。 これにより、Nginxはすべてのクライアントリクエストを処理できるようになります。 これは、Nginxの高速な処理速度と、多数の接続を同時に処理する機能を利用しています。

Nginxが得意とする静的コンテンツの場合、ファイルまたはその他のディレクティブが迅速かつ直接クライアントに提供されます。 PHPファイルなどの動的コンテンツの場合、NginxはリクエストをApacheにプロキシし、Apacheは結果を処理して、レンダリングされたページを返すことができます。 その後、Nginxはコンテンツをクライアントに戻すことができます。

この設定は、Nginxが仕分け機として機能できるため、多くの人に適しています。 可能なすべてのリクエストを処理し、ネイティブに処理する機能がないリクエストを渡します。 Apacheサーバーが処理するように要求される要求を削減することにより、Apacheプロセスまたはスレッドが占有されているときに発生するブロッキングの一部を軽減できます。

この構成では、必要に応じてバックエンドサーバーを追加することで、水平方向のスケーリングも容易になります。 Nginxは、複数のサーバーにリクエストを渡すように構成できるため、この構成のパフォーマンスが向上します。

結論

ApacheとNginxはどちらも強力で、柔軟性があり、機能があります。 どのサーバーが最適かを判断するのは、主に、特定の要件を評価し、予想されるパターンでテストする機能です。

これらのプロジェクトには違いがあり、本番環境でいずれかのソリューションを使用するために必要な生のパフォーマンス、機能、および実装時間に非常に大きな影響を与えます。 目的に最も適したソリューションを使用してください。