Python ランタイムアーキテクチャ
WSGI/ASGIサーバーとリクエスト処理フロー
アーキテクチャ概要
クライアント
→ HTTP/HTTPS →
リバースプロキシ
Nginx
→ HTTP / Unix Socket →
WSGIサーバー
Gunicorn / uWSGI
→
Python
インタープリター
→
Application
Django / Flask / FastAPI
WSGI vs ASGI
WSGI (Web Server Gateway Interface)
- • 同期処理
- • Django, Flaskで使用
- • Gunicorn, uWSGI
- • シンプルで安定
ASGI (Asynchronous SGI)
- • 非同期処理
- • FastAPI, Starlette, Django 3.0+
- • Uvicorn, Daphne
- • WebSocket対応、高並行
データフローと制限ポイント
1
Nginx (リバースプロキシ)
client_max_body_size, proxy_read_timeout
proxy_connect_timeout, proxy_send_timeout
proxy_connect_timeout, proxy_send_timeout
2
Gunicorn / uWSGI
timeout, workers, worker_connections
limit-post (uWSGI)
limit-post (uWSGI)
3
Python / フレームワーク
Django: DATA_UPLOAD_MAX_MEMORY_SIZE, FILE_UPLOAD_MAX_MEMORY_SIZE
Flask: MAX_CONTENT_LENGTH
Flask: MAX_CONTENT_LENGTH
WSGIサーバー比較
| 項目 | Gunicorn | uWSGI | Uvicorn (ASGI) |
|---|---|---|---|
| プロトコル | WSGI | WSGI + 独自 | ASGI |
| 設定の複雑さ | シンプル | 複雑(多機能) | シンプル |
| パフォーマンス | 良好 | 高い | 非常に高い |
| 非同期対応 | gevent worker | async mode | ネイティブ |
| 推奨用途 | Django, Flask | 高パフォーマンス要件 | FastAPI, async処理 |
Gunicornワーカーモデル
sync (デフォルト)
- • 同期ワーカー
- • 1リクエスト/ワーカー
- • CPU bound処理向け
gevent / eventlet
- • 非同期ワーカー
- • 多数の同時接続
- • I/O bound処理向け
gthread
- • スレッドワーカー
- • マルチスレッド処理
- • GIL制約あり
ワーカー数の目安: (2 × CPUコア数) + 1
例: 4コアCPU → 9 workers
各層の設定詳細
Nginx
1 # /etc/nginx/sites-available/app.conf 2 upstream app_server { 3 server unix:/run/gunicorn.sock fail_timeout=0; 4 # または server 127.0.0.1:8000; 5 } 6 7 server { 8 listen 80; 9 server_name example.com; 10 11 client_max_body_size 100M; # リクエストボディ制限 12 client_body_timeout 60s; 13 14 location / { 15 proxy_pass http://app_server; 16 proxy_set_header Host $host; 17 proxy_set_header X-Real-IP $remote_addr; 18 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 19 20 proxy_connect_timeout 60s; 21 proxy_read_timeout 60s; # Gunicornからの応答待ち 22 proxy_send_timeout 60s; 23 } 24 25 location /static/ { 26 alias /var/www/app/static/; # 静的ファイルはNginxから直接 27 } 28 }
Gunicorn
1 # gunicorn.conf.py 2 bind = "unix:/run/gunicorn.sock" 3 # または bind = "0.0.0.0:8000" 4 5 # ワーカー設定 6 workers = 9 # (2 * CPU) + 1 7 worker_class = "sync" # sync, gevent, gthread, uvicorn.workers.UvicornWorker 8 threads = 1 # gthread用 9 10 # タイムアウト 11 timeout = 30 # ワーカータイムアウト (秒) 12 graceful_timeout = 30 # graceful shutdown待ち 13 keepalive = 2 # Keep-Alive接続のタイムアウト 14 15 # リクエスト制限 16 limit_request_line = 4094 # リクエストライン最大長 17 limit_request_fields = 100 # ヘッダー最大数 18 limit_request_field_size = 8190 19 20 # ロギング 21 accesslog = "/var/log/gunicorn/access.log" 22 errorlog = "/var/log/gunicorn/error.log" 23 loglevel = "info" 24 25 # プロセス管理 26 max_requests = 1000 # ワーカーリサイクル 27 max_requests_jitter = 50 # リサイクルにランダム性追加 28 preload_app = True # アプリ事前ロード
Django settings.py
1 # settings.py 2 # ファイルアップロード制限 3 DATA_UPLOAD_MAX_MEMORY_SIZE = 104857600 # 100MB (POSTデータ) 4 FILE_UPLOAD_MAX_MEMORY_SIZE = 104857600 # 100MB (ファイル) 5 DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000 # フィールド数制限 6 7 # 一時ファイル設定 8 FILE_UPLOAD_TEMP_DIR = "/tmp" 9 FILE_UPLOAD_PERMISSIONS = 0o644 10 11 # セキュリティ 12 ALLOWED_HOSTS = ["example.com", "www.example.com"] 13 CSRF_TRUSTED_ORIGINS = ["https://example.com"]
FastAPI + Uvicorn
1 # main.py 2 from fastapi import FastAPI, UploadFile 3 from fastapi.middleware.cors import CORSMiddleware 4 5 app = FastAPI() 6 7 # ファイルアップロード 8 @app.post("/upload/") 9 async def upload_file(file: UploadFile): 10 # file.size でサイズチェック可能 11 contents = await file.read() 12 return {"filename": file.filename, "size": len(contents)} 13 14 # 起動コマンド 15 # uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4 --timeout-keep-alive 30
よくあるエラーと対処
[CRITICAL] WORKER TIMEOUT
原因: Gunicornワーカーがtimeout秒以内に応答しなかった
対処:
- timeout値を増加
- 重い処理は非同期タスク(Celery)に移動
- geventワーカーを検討
502 Bad Gateway
原因: Gunicornがダウン、またはソケット接続失敗
確認箇所:
- Gunicornプロセスの状態確認
- ソケットファイルの権限
- Nginxのupstream設定
MemoryError
原因: ワーカープロセスのメモリ枯渇
対処:
- max_requests でワーカーを定期リサイクル
- メモリリークの調査
- 大きなデータはストリーミング処理
監視項目
Gunicorn
- • ワーカープロセス数
- • リクエスト処理時間
- • メモリ使用量/ワーカー
- • ワーカーリスタート回数
アプリケーション
- • リクエスト/秒
- • エラー率 (4xx/5xx)
- • データベースクエリ時間
- • 外部API呼び出し時間
systemd設定例
1 # /etc/systemd/system/gunicorn.service 2 [Unit] 3 Description=Gunicorn daemon for Django 4 After=network.target 5 6 [Service] 7 User=www-data 8 Group=www-data 9 WorkingDirectory=/var/www/app 10 ExecStart=/var/www/app/venv/bin/gunicorn \ 11 --config gunicorn.conf.py \ 12 myapp.wsgi:application 13 ExecReload=/bin/kill -s HUP $MAINPID 14 Restart=on-failure 15 RestartSec=5 16 17 # リソース制限 18 MemoryMax=2G 19 CPUQuota=200% 20 21 [Install] 22 WantedBy=multi-user.target