NginxとGunicornなどが必要なのはなぜですか?


219

次の質問に対する過度に単純化された答えを探しています。私はNginxがGunicornのようなものと一緒にどのように機能するかについて基礎的な理解を構築しようとしています。

NginxにDjangoアプリをデプロイするには、NginxとGunicornなどの両方が必要ですか?

もしそうなら、実際にHTTPリクエストを処理するのは何ですか?

追伸 Apacheとmod_wsgiを使いたくありません!


Apacheとmod_wsgiは、djangoアプリケーションとhttp要求の間のブリッジを実装する最も簡単な方法であり、実稼働環境でも非常に有効です。多くの開発者にとって、これは知っていれば「Apacheはnginxよりも優れている」ことを意味しますが、「ベータマックスはVHSよりも優れている」ため、悲しいことに、ドグマのルール
-MagicLAMP

回答:


314

非常に単純化:Pythonを実行するものが必要ですが、Pythonはすべてのタイプのリクエストを処理するのに最適ではありません。

[免責事項:私はGunicorn開発者です]

それほど単純化されていない:使用するアプリサーバー(Gunicorn、mod_wsgi、mod_uwsgi、cherrypy)に関係なく、あらゆる種類の非自明な展開には、Djangoアプリが処理してはならないリクエストを処理するアップストリームがあります。このようなリクエストの簡単な例は、静的アセット(images / css / js)の提供です。

これにより、従来の「3層アーキテクチャ」の2つの最初の層が作成されます。つまり、ウェブサーバー(あなたの場合はNginx)は、画像と静的リソースに対する多くのリクエストを処理します。動的に生成する必要があるリクエストは、アプリケーションサーバー(例ではGunicorn)に渡されます。(余談ですが、3層のうち3番目はデータベースです)

歴史的に言えば、これらの各層は別々のマシンでホストされます(最初の2層には複数のマシンが存在する可能性が高くなります。つまり、5つのWebサーバーが2つのアプリサーバーにリクエストをディスパッチします。

現代では、あらゆる形状とサイズのアプリケーションがあります。週末のプロジェクトや中小企業のサイトが実際に複数のマシンの馬力を必要とするわけではなく、単一のボックスで非常に快適に動作します。これにより、ホスティングソリューションの配列に新しいエントリが生まれました。一部のソリューションでは、アプリサーバーとWebサーバー(Apache httpd + mod_wsgi、Nginx + mod_uwsgiなど)を結合します。また、これらのWebサーバーとアプリサーバーの組み合わせの1つと同じマシンでデータベースをホストすることも珍しくありません。

Gunicornの場合、Nginxのプロキシ動作に依存しながら、Nginxから物事を分離するという特定の決定(RubyのUnicornからのコピー)を行いました。具体的には、Gunicornがインターネットから直接接続を読み取らないと仮定できる場合、遅いクライアントを心配する必要はありません。これは、Gunicornの処理モデルが非常に単純であることを意味します。

また、この分離により、Gunicornを純粋なPythonで作成できるため、パフォーマンスに大きな影響を与えずに開発コストを最小限に抑えることができます。また、ユーザーは他のプロキシを使用することもできます(正しくバッファリングすることを前提としています)。

HTTPリクエストを実際に処理するものについての2番目の質問については、単純な答えはGunicornです。完全な答えは、NginxとGunicornの両方がリクエストを処理することです。基本的に、Nginxはリクエストを受信し、それが動的なリクエスト(一般にURLパターンに基づく)である場合、そのリクエストをGunicornに与え、Gunicornがそれを処理してから、レスポンスをNginxに返します。クライアント。

最後に、はい。Djangoを適切に展開するには、NginxとGunicorn(または同様のもの)の両方が必要です。特にDgingoをNginxでホストすることを検討している場合は、Gunicorn、mod_uwsgi、CherryPyをDjango側の候補として調査します。


14
このような詳細な答えを書くのに時間を割いてくれてありがとう!この「3層アーキテクチャ」に関する推奨読書はありますか?
午前

5
すばらしい答えですが、遅いクライアントの問題を理解していません。
マッドスキャーン14

3
@MadsSkjern私はここで推測していますが、すべてのクライアントが高速であると仮定すれば、ワーカープロセスの固定プールを使用でき、クライアントの待機中にそれらの多くまたはすべてがブロックされる場合にコーディングする必要はありません。
ジョナサンハートリー14


7
私のdjangoアプリはjsonだけに静的コンテンツを提供しません。gunicornとnginxなしで行くことはできません
Sar009

27

私はこの説明がシンプルで気に入った:

Nginxは外の世界に直面します。ファイルシステムから直接メディアファイル(画像、CSSなど)を提供します。ただし、Djangoアプリケーションと直接通信することはできません。アプリケーションを実行し、Webから要求をフィードし、応答を返すものが必要です。

それがGunicornの仕事です。GunicornはUnixソケットを作成し、wsgiプロトコルを介してnginxへの応答を提供します-ソケットは双方向にデータを渡します。

The outside world <-> Nginx <-> The socket <-> Gunicorn

https://gist.github.com/Atem18/4696071


他の人が疑問に思っている場合に備えて、ソケットである必要はありません。
akshay

0

私は過度に単純化された答えを探しています...

NginxにDjangoアプリをデプロイするには、NginxとGunicornなどの両方が必要ですか?

もしそうなら、実際にHTTPリクエストを処理するのは何ですか?

過度に単純化された答え:

はい。

NginxとGunicornの両方。

Nginxにデプロイしているので、もちろんNginxが必要です。

WebフレームワークであるDjangoをデプロイしているため、Webサーバー(Nginx)とWebフレームワーク(Django)の間の対話を橋渡しするものが必要です。Pythonの世界では、そのようなものはWSGIサーバーと呼ばれます(ただし、ミドルウェアのように思えます)。その例にはGunicornとuWSGIが含まれます。リクエストを処理するとき、NginxはリクエストをGunicornまたはuWSGIにプロキシします。GunicornまたはuWSGIはDjangoコードを呼び出し、レスポンスを返します。

このドキュメントとポールの回答は、あなたがそれをよりよく学ぶのに役立ちます。


0

Gunicornはリソースの無駄です。一番上のdjangoでgunicornを実行し、その上で再びnginxを実行する代わりに、ポートでリッスンするdjangoにプロキシパスを渡すことができます。ベンチマークでは、非常に顕著な速度の増加が見られました。Nginxは、djangoへの直接リクエストを簡単に処理できます。Gunicornは、通常の道路上の高架道路(実際にはより低速の高架道路)に過ぎません。ただ座ってあなたのリソースを消費し、あなたのウェブサイトを動かしていると主張しようとします。

nginxは基本的にすべてのリクエストをバッファリングし、静的ファイルリクエストを単独で処理します(そのように設定した場合)。そして、すべての動的コンテンツを別のサーバーにプロキシします(gunicorn / django)。

Gunicornには、単にリクエストをアプリケーションに渡す以外の用途はありません。ストローのように、グラスから直接飲むか、限られたペースでストローから飲むことができます(ここで飲む人はジャンゴです)。そしてnginxはあなたにジュースのグラスを持ってきたウェイターです。

私はベンチマークを行い、これを見つけました-gunicornを使用:22k req / s gunicornなし:34k req / s

あなたのサイトは重い負荷で余分な要求を必要とします。


1
本番環境で開発サーバーを実行することについて話していますか?!
マイケルハンプトン

開発サーバーは、運用サーバー(nginxなど)の背後で実行できます。要求が正しい場所で取得されるため、セキュリティと効率は運用サーバーによって処理されます。WSGI +フラスコだけを使用するようなものです。代わりに、nginx + djangoのみを使用できます(gunicornなどのミドルウェアの占有なし)。重い負荷でセットアップをテストしてください。理解できます。
ShadowDoom

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.