web-dev-qa-db-ja.com

Nginxをリバースプロキシとして設定するのが良いのはなぜですか?

DjangoサイトがNginxを介したリバースプロキシを使用してGunicornで実行されています。Nginxは余分な不要なオーバーヘッドではありませんか?Gunicornの上に追加するとどうなりますか?

42
TheOne

ここでは、クライアントの動作が遅いことと、構成がそれをどのように処理するかに焦点を当てますが、それが唯一の利点であると信じたくありません。低速クライアントにメリットをもたらす同じ方法は、高速クライアント、SSL処理、トラフィックの急増への対処、およびインターネットでHTTPを提供するその他の側面にもメリットがあります。

Gunicornはpre-forkソフトウェアです。アプリサーバーへのロードバランサーやサービス間の通信など、レイテンシの低い通信の場合、プリフォークシステムは非常に成功する可能性があります。リクエストを処理するためにプロセスを起動するのにコストはかかりません。また、1つのプロセスを1つのリクエストの処理専用にすることができます。これらを排除することで、同時接続の数が、それらを処理するために利用可能なプロセスの数を超えるまで、全体的に高速で効率的なシステムを実現できます。

あなたの状況では、インターネット経由で待ち時間の長いクライアントを扱っています。これらの遅いクライアントは、同じプロセスを拘束する可能性があります。 QPSが重要な場合、アプリケーションコードは、要求をできるだけ早く受信、処理、および解決して、別の要求に移ることができるようにする必要があります。遅いクライアントがシステムと直接通信する場合、クライアントはそのプロセスを拘束し、速度を落とします。リクエストをできるだけ早く処理して破棄する代わりに、そのプロセスは遅いクライアントを待つ必要もあります。実効QPSが低下します。

CPUとメモリのコストが非常に少ない状態で多数の接続を処理することが、Nginxのような非同期サーバーの得意分野です。これらは、多数のクライアントを同時に処理することに長けているため、遅いクライアントによる同じマイナスの影響を受けません。 Nginxの場合、最新のハードウェアで実行すると、一度に数万の接続を処理できます。

フォーク前のサーバーの前にあるNginxは素晴らしい組み合わせです。 Nginxはクライアントとの通信を処理し、遅いクライアントを処理することによるペナルティは受けません。バックエンドがそれらの要求を処理できるのと同じ速さでバックエンドに要求を送信し、サーバーリソースで可能な限り効率的にバックエンドを有効にします。バックエンドはそれを計算するとすぐに結果を返し、Nginxはその応答をバッファリングして、遅いクライアントに自分のペースでフィードします。その間、遅いクライアントがまだ結果を受け取っていても、バックエンドは別のリクエストの処理に進むことができます。

53
blueben

@bluebenは正しいです。リバースプロキシが使用されない場合に発生する可能性のある特定の一般的な例は、プロキシがなくトラフィックが急増している場合に、バックエンドデータベースがデータベース接続ハンドルを使い果たす可能性があることです。これは、@ bluebenで説明されているように、接続の解放が遅いためです。

データベースハンドルの不足を確認する最初の本能は、より多くのデータベース接続をサポートすることかもしれません。ただし、アプリの前にリバースプロキシを追加すると、高負荷に必要なデータベース接続の数が大幅に減少し、安定します。トラフィックが急増した場合、データベース接続レベルが急上昇することはほとんどありません。

Nginxは、静的コンテンツの提供、キャッシング、その他のさまざまなHTTPタスクにも優れているため、アプリサーバーをアプリサーバーに集中させることができます。

2
Mark Stosberg

@naill Doneganは上記のコメントでこれについて言及していますが、回答を保証するのに十分重要です。

Nginxは、gunicornが処理しないスローロリス攻撃を阻止します。

0
rox0r