DjangoのuWSGI,Gunicorn,Daphne,Uvicornとかって何?どれを選べばいいの?

DjangoのuWSGI・Gunicorn・Daphne・Uvicornの違いを解説する記事のアイキャッチ Python
icatch image

Introduction

Djangoの勉強をしているときに、uWSGIを設定しましょうとかGunicornで起動しましょうとかを記事で見たことはありませんか?
さらには Daphne が ASGI に対応していますという記事もあったりしますよね。
一方で、公式チュートリアルでは python manage.py runserver を実行してDjangoアプリを起動しています。uWSGIだとかGunicornだとかは出てきていません。

Djangoを業務で使う立場として私自身このあたりを一度整理したいと思い、この記事を書きました。
間違った理解や不十分な記述があればご指摘いただけますと幸いです。

どれが良いかだけ知りたい人のために、とりあえず結論を書いておきます!
・基本は Daphne
・性能が欲しいなら Uvicorn
特殊要件なら Hypercorn
uWSGIとGunicornは新規プロダクトでは候補に上がりづらい

Webサーバ/アプリケーションサーバ/Webフレームワーク

※本記事ではVPSのようなサーバマシンがWebアプリケーションを提供していると想定しています。

この章では WebサーバアプリケーションサーバWeb フレームワークについて紹介します。
すでにご存知の方は次の章に飛んでください。

本記事で紹介する構成のイメージとなります。

Webサーバ (HTTPサーバ)

Webブラウザやスマホアプリなどのクライアントは、データの取得や送信などのHTTPリクエストをサーバに送信します。
一方でサーバにはHTTPリクエストの受け取りと、リクエストを適切なプログラムに振り分ける窓口が必要となります。その役割を担うのが NginxApache のようなWebサーバです。

Webサーバの主な役割は次のとおりです。

  • ブラウザから届くHTTPリクエストを受け取る
  • SSL/TLS(https)暗号化を処理する
  • 静的ファイル(画像・CSS・JavaScript)を高速に返す
  • Webアプリ(Django など)への中継役(リバースプロキシ)になる

アプリケーションサーバ

Webサーバとは別に「アプリケーションサーバ」という役割があります。
後述するWebフレームワークは、HTTPのコネクションを直接扱う仕組みを持っていないため、Webフレームワークの処理を実行してくれる専用のソフトウェアが必要になります。

その役割を担うのが、アプリケーションサーバ です。
例えば、Ruby on RailsではPumaやUnicornがその役割となります。

アプリケーションサーバは主に次のようなことを行います。

  • OSのソケットを開いてリクエストを受け取る
  • マルチプロセス / マルチスレッドの管理
  • ワーカー数の管理、スケール
  • Webフレームワークをロードして実行する
  • リクエストのキュー処理
  • graceful reload / graceful stop(落とさずに再起動)

Webサーバと違い、Webアプリの「処理部分」を動作・管理する存在です。
Webフレームワークで実装された処理をHTTPリクエストに対して割り振り、複数の処理を並列で処理して管理することができます。

つまりWebサーバとアプリケーションサーバは役割が全く違うものです!

Webフレームワーク

本記事で取り扱うDjangoはWebフレームワークです。
アプリケーションの中身を作る仕組みであり、Webサーバが受け付けたリクエストに対して、以下のような処理を行います。

  • URLごとの処理(URL routing)
  • データベースとのやり取り
  • テンプレート描画
  • 認証・セッション管理

これまでのWebサーバ、アプリケーションサーバ、Webフレームワークを例えるなら

  • Webサーバ = 玄関で荷物を受け取り、担当へ取り次ぐ受付係
  • アプリケーションサーバ = 荷物の内容を判断して処理する担当者
  • Webフレームワーク = URLなどのリクエストの種類に対して処理を対応させる説明書

Django

Djangoの役割

DjangoはWebフレームワークです。
そして、Djangoの仕組みについて勘違いされがちな理由だと思いますが、
Djangoはアプリケーションサーバではありません

HTTPリクエストを受け付ける能力はなく、
あくまでデータベースを読み書きしたりWebページを動的に生成したりすることしかできません。

Django が担当する役割

  • どのURLにどの処理を紐づけるか決める(URL routing)
  • HTMLテンプレートの描画
  • データベース操作(独自ORM)
  • 認証やセッション管理
  • CSRF対策やセキュリティ機能
  • フォーム処理、バリデーション
  • ミドルウェアによる共通処理(ログ、認可など)

WSGIとASGI

Djangoをフレームワークとして扱うためには、アプリケーションサーバとやり取りするための共通の取り決めが必要になります。そのインターフェースの定義として、WSGIとASGIの2種類があります。

WSGI(Web Server Gateway Interface)

WSGIはPython製Webアプリのために作られた同期処理専用のインターフェースです。

  • リクエストは1つずつ順番に処理
  • WebSocketやストリーミングとは相性が悪い
  • Django 1.x〜2.x では標準

昔ながらのウェブアプリには十分でしたが、
最近のリアルタイム通信には向いていません。

ASGI(Asynchronous Server Gateway Interface)

ASGIはWSGIの後継として登場した非同期対応のインターフェースです。

  • 非同期処理 / async / await 対応
  • 同期処理も動く
  • WebSocket や長時間接続を扱える
  • Django 3.0 以降で公式サポート

現在のDjangoプロジェクトは、ASGIを前提に構築するのが標準的になっています。

既存の def view(request): 形式の同期ビューもそのまま動作するため、
「ASGIにしたら全部 async に書き直さないといけない」ということはありません。

結局uWSGIとかGunicornとかDaphneとかって?

uWSGI, Gunicorn, Daphneはアプリケーションサーバです。

DjangoがHTTPリクエストを処理する機能が無いなら、代わりに処理してあげる人が必要になります。それを担っているのが彼らです。
Nginxなど外向きのWebサーバに対してはHTTPを話しDjangoやFlaskなどのWebフレームワークにはWSGI/ASGIを話す 翻訳者 のイメージが近いでしょうか。

それぞれのプロトコルと特徴について紹介していきます。

uWSGI

uWSGIはWSGI時代に作られた古くからあるアプリケーションサーバで、
Python製Webアプリの本番運用では長い間定番でした。

一番の特徴は、NginxなどのWebサーバとuWSGIの間ではHTTPを使わないことです。
昔の機器ではサーバ内部でのやり取りにHTTPを使うのは冗長とされていたため、無駄の少ないuWSGI Protocolでアプリケーションサーバと繋いでいました。
HTTPに比べて幾分かは効率的ですが、現代のWebアプリケーションのボトルネックはDBのI/Oや動的な描画であり、HTTPとuWSGI Protocolでの速度差は誤差と言えるでしょう。

特徴

  • 多機能
  • 再起動やプロセス管理も安定
  • 設定が複雑
  • uWSGI独自設定のため、習得しても他のフレームワークに移行すると学習が無駄になる
  • WSGI 対応
  • ASGI(WebSocket や async)には非対応

Django 4.x 以降の主流は ASGI対応 なので、
uWSGIは現在では “レガシーな選択肢” と言えます。
新しくDjangoを学ぶ方にはおすすめできません。

通信のイメージ
client ⇔ HTTP(s) ⇔ Nginx ⇔ uWSGI Protocol uWSGIWSGI ⇔ Django

Gunicorn

uWSGIの次に広く使われたのが Gunicorn です。
設定も比較的簡単で、WSGI環境では最も使われています。

こちらはuWSGIと違い、WebサーバとはHTTPで通信します。
前述の通り、HTTPでのリバースプロキシは冗長ですが現代では誤差です。
それならば一般的なプロトコルであるHTTPを使う方が設定や環境構築など何かと便利なわけですね。

特徴

  • シンプルで扱いやすい
  • 設定が簡単
  • WSGI 対応
  • ASGI(WebSocket や async)には非対応

こちらも、ASGIが標準になりつつある今では新規プロダクトの候補になりづらいです。

通信のイメージ
client ⇔ HTTP(s) ⇔ Nginx ⇔ HTTP GunicornWSGI ⇔ Django

Daphne

Daphneは Django Channels プロジェクトの一部として開発されたASGI対応のアプリケーションサーバ です。
DjangoがASGI(async / WebSocket)に正式対応したことで登場した基本的なASGIサーバです。

特徴としては非常にシンプルで、Djangoが提供する asgi.py をそのまま読み込むだけで動作します。特にWebSocketを扱いたい場合や、リアルタイム通信が必要な場合に選ばれやすいアプリケーションサーバです。

  • ASGI(async / WebSocket)対応
  • Djangoとの相性が良い(公式コミュニティ発)
  • 設定も比較的シンプル
  • 性能はUvicornに劣る

今からDjangoを使うならとりあえずこれでOKです。
Djangoの公式ドキュメントでも ASGIの例として触れられているため、
「ASGIを触ってみたい」という方にとっては最も導入しやすいサーバです。
asgi : https://docs.djangoproject.com/ja/5.2/howto/deployment/asgi/

DaphneはベンチマークでUvicornに劣ることが多いですが、中規模までなら十分な性能と言えます。個人開発や最初の1台の運用としておすすめです!

通信のイメージ
client ⇔ HTTP(s) ⇔ Nginx ⇔ HTTPDaphneASGI ⇔ Django

UvicornとHypercorn

Daphneと同じくASGI対応のアプリケーションサーバです。
以下の用途と合致するならこちらの採用も検討すると良さそうです!

Uvicorn

Uvicorn は とにかく軽量で速い ことで知られるASGIサーバです。
FastAPI などの高速フレームワークでよく使われているため、Pythonの非同期処理界隈では採用率が伸びています。

  • ASGI 対応
  • 圧倒的に高速(イベントループの最適化)
  • 軽量・シンプル
  • 実運用での実績が豊富(FastAPI が標準として採用)

Hypercorn

Hypercorn もASGI対応のサーバで Uvicorn より柔軟性や拡張性が高点が特徴です。

  • ASGI 対応
  • HTTP/1.1, HTTP/2, HTTP/3 をサポート(幅広いプロトコル対応)
  • WebSocket, 長時間接続にも対応
  • 設定項目が豊富で柔軟

開発用サーバ

python manage.py runserver

公式チュートリアルやDjangoの入門記事でよく使われているものです。
上記のコマンドはDjangoに付属している開発用の簡易サーバで、
本番環境での利用は想定されていません

  • Djangoが自前で持っている簡易 Webサーバ
  • 自動リロードが便利(コード変更で即反映)
  • デバッグ用の例外画面が表示される
  • シングルスレッド寄りで性能が弱い
  • 高負荷・大量アクセスを想定していない
  • 本番運用に必要なプロセス管理機能がない

runserverは便利な開発用サーバであり簡易的なサーバです。
本番環境で外部に公開することは避けてください

Conclusion

ここまで、Webサーバ・アプリケーションサーバ・Webフレームワークの役割から、
uWSGI / Gunicorn / Daphne / Uvicorn / Hypercorn の違いまで順番に整理してきました。

Djangoはあくまで Webフレームワーク であり、
HTTPリクエストを受け付ける機能は持っていません。

そのため本番環境では、NginxのようなWebサーバと、
ASGI対応のアプリケーションサーバ が必要になります。

現在のDjangoはASGIに公式対応しているため、下記の選択が良さそうです。

  • まずは Daphne(公式寄りで扱いやすい)
  • 性能重視なら Uvicorn
  • 特殊要件(HTTP/2/3)が必要なら Hypercorn

逆に、WSGI前提で作られた uWSGI / Gunicorn は、
新規プロダクトでは候補には上がりづらいと言えるでしょう。

推奨構成の最小例
Nginx等(HTTPs終端) → Uvicorn / Daphne → Django(ASGI)

最後に重要なポイントをまとめておきます。

  • Django ≠ アプリケーションサーバ
  • runserver はあくまで開発用(本番禁止
  • 現代の Django は ASGI(非同期)を前提に選ぶ

この記事が、Djangoの本番構成やサーバ周りの理解を深める一助になれば幸いです。
もし間違いがあればぜひご指摘ください。

この記事が役に立ちましたらぜひ左下のGoodボタンをお願いします!
皆様のGoodが執筆の励みになります。

コメント

タイトルとURLをコピーしました