WSGI サーバーの種類と選び方(Gunicorn / uWSGI / Waitress)

本番環境で Python Web アプリケーションを運用するには、開発用サーバーではなく本番向けの WSGI サーバーが必要になる。Gunicorn、uWSGI、Waitress はそれぞれ異なる設計思想を持ち、用途に応じた選択が求められる。

なぜ本番用サーバーが必要か

Flask や Django に付属する開発用サーバーは、デバッグ機能を優先して設計されている。自動リロード、詳細なエラー表示、シングルスレッド動作などは開発には便利だが、本番環境には不向きだ。

開発用サーバー

シングルプロセス・シングルスレッドで動作。同時リクエストを処理できず、パフォーマンスもセキュリティも考慮されていない。

本番用 WSGI サーバー

マルチプロセス・マルチスレッドで並行処理に対応。堅牢性、パフォーマンス、運用機能を備え、長期稼働に耐える設計。

本番用サーバーは、複数のワーカーでリクエストを並行処理し、障害時の自動復旧、graceful restart、シグナルハンドリングなどの運用機能を提供する。

Gunicorn

Gunicorn(Green Unicorn)は、Ruby の Unicorn に影響を受けた Python 製の WSGI サーバーである。シンプルさと使いやすさを重視した設計で、Python エコシステムでは最も広く使われている。

特徴

プリフォークモデル

マスタープロセスが複数のワーカープロセスを事前に生成(プリフォーク)する。各ワーカーが独立してリクエストを処理するため、一つのワーカーがクラッシュしても他に影響しない。

設定のシンプルさ

コマンドラインオプションか Python ファイルで設定を行う。必要最小限の設定で動作し、複雑な設定ファイル形式を覚える必要がない。

基本的な使い方

# インストール
pip install gunicorn

# 起動(app.py の application オブジェクトを起動)
gunicorn app:application

# ワーカー数を指定
gunicorn -w 4 app:application

# バインドアドレスを指定
gunicorn -b 0.0.0.0:8000 -w 4 app:application

Flask アプリケーションの場合は、アプリケーションオブジェクトを指定する。

# Flask の場合(app.py で app = Flask(__name__) と定義)
gunicorn app:app

# ファクトリパターンの場合
gunicorn "app:create_app()"

ワーカータイプ

Gunicorn は複数のワーカータイプをサポートしており、アプリケーションの特性に応じて選択できる。

# sync ワーカー(デフォルト、同期処理)
gunicorn -k sync app:app

# gevent ワーカー(非同期 I/O)
pip install gevent
gunicorn -k gevent app:app

# eventlet ワーカー(非同期 I/O)
pip install eventlet
gunicorn -k eventlet app:app

# gthread ワーカー(スレッドベース)
gunicorn -k gthread --threads 4 app:app

I/O バウンドなアプリケーション(外部 API 呼び出しが多いなど)では、gevent や gthread が効果的だ。

uWSGI

uWSGI は、C で実装された高機能な WSGI サーバーである。WSGI だけでなく、様々なプロトコルとプラグインをサポートする汎用的なアプリケーションサーバーだ。

特徴

高いパフォーマンス

C 言語で実装されており、純粋な Python 実装よりもオーバーヘッドが小さい。大量のリクエストを効率的に処理できる。

豊富な機能

キャッシュ、ルーティング、ロードバランシング、統計情報、cron 機能など、運用に必要な機能を内蔵。設定項目は数百に及ぶ。

基本的な使い方

# インストール
pip install uwsgi

# 起動
uwsgi --http :8000 --wsgi-file app.py --callable application

# ワーカー数を指定
uwsgi --http :8000 --wsgi-file app.py --callable application --processes 4

# スレッドを有効化
uwsgi --http :8000 --wsgi-file app.py --callable application --processes 4 --threads 2

設定ファイル(INI 形式)を使うのが一般的だ。

# uwsgi.ini
[uwsgi]
http = :8000
wsgi-file = app.py
callable = application
processes = 4
threads = 2
master = true
vacuum = true
die-on-term = true
# 設定ファイルで起動
uwsgi --ini uwsgi.ini

Nginx との連携

本番環境では、Nginx をリバースプロキシとして前段に置き、uWSGI プロトコルで通信するのが一般的だ。

# uwsgi.ini(Nginx 連携用)
[uwsgi]
socket = /tmp/uwsgi.sock
chmod-socket = 666
wsgi-file = app.py
callable = application
processes = 4
threads = 2
master = true

HTTP ではなく Unix ソケットを使うことで、通信オーバーヘッドを削減できる。

Waitress

Waitress は、純粋な Python で実装された WSGI サーバーである。Windows でも動作し、依存関係が少ないのが特徴だ。

特徴

クロスプラットフォーム

Unix 系だけでなく Windows でも問題なく動作する。Gunicorn や uWSGI が Unix 系に最適化されているのとは対照的。

シンプルな実装

外部依存がなく、pip でインストールするだけで使える。設定項目も少なく、すぐに本番運用を始められる。

基本的な使い方

# インストール
pip install waitress

# 起動
waitress-serve --port=8000 app:application

# ホストとポートを指定
waitress-serve --host=0.0.0.0 --port=8000 app:application

# スレッド数を指定
waitress-serve --threads=4 app:application

Python コードから起動することもできる。

from waitress import serve
from app import application

serve(application, host='0.0.0.0', port=8000, threads=4)

特性

Waitress はスレッドベースのアーキテクチャを採用しており、マルチプロセスはサポートしていない。そのため、CPU バウンドな処理には向かないが、I/O バウンドな処理には十分なパフォーマンスを発揮する。

サーバー比較

各サーバーの特性を比較する。

項目GunicornuWSGIWaitress
実装言語PythonCPython
Windows対応×

設定の複雑さについては、Gunicorn が最もシンプルで、uWSGI は高機能だが学習コストが高い。Waitress はその中間に位置する。

パフォーマンス面では、uWSGI が最も高速だが、Gunicorn も十分な性能を持つ。Waitress はやや劣るものの、多くのユースケースで問題ない水準だ。

選択の指針

どのサーバーを選ぶかは、プロジェクトの要件によって決まる。

シンプルに始めたい

Gunicorn を選択

コマンドライン数行で本番運用開始

Gunicorn は、特別な理由がなければ最初の選択肢として適している。設定がシンプルで、ドキュメントも豊富、コミュニティも活発だ。

uWSGI は、高度なカスタマイズが必要な場合や、最大限のパフォーマンスを追求する場合に選択する。ただし、設定の複雑さを考慮する必要がある。

Waitress は、Windows 環境での運用や、依存関係を最小限に抑えたい場合に有力な選択肢となる。Pyramid フレームワークの公式推奨サーバーでもある。

実際のデプロイ構成

本番環境では、WSGI サーバーの前段にリバースプロキシ(Nginx など)を配置するのが一般的だ。

クライアント

Nginx(静的ファイル配信、SSL 終端、ロードバランス)

Gunicorn / uWSGI / Waitress

Python アプリケーション

Nginx は静的ファイルの配信、SSL/TLS 終端、リクエストのバッファリング、複数の WSGI サーバーへのロードバランシングなどを担当する。この構成により、WSGI サーバーはアプリケーション処理に専念できる。

どのサーバーを選んでも、WSGI 仕様に準拠したアプリケーションであれば、設定を変えるだけで切り替えられる。まずは Gunicorn で始めて、必要に応じて他のサーバーを検討するのが現実的なアプローチだ。