01-2. 為什麼需要 Gunicorn

⏱️ 閱讀時間: 5 分鐘 🎯 難度: ⭐ (超級簡單)


💡 2025 年更新:關於 ASGI

在開始之前,先了解兩種方案:

方案適用對象說明
ASGI (Uvicorn) 🆕Django 3.0+ 新專案Python 官方異步標準,推薦新專案使用
WSGI (Gunicorn)Django < 3.0 或舊專案成熟穩定,本系列文章主要介紹此方案
# 新專案推薦(Django 3.0+)
pip install uvicorn[standard]
uvicorn myproject.asgi:application --workers 4

# 舊專案或 WSGI 應用(本文重點)
pip install gunicorn
gunicorn myproject.wsgi:application --workers 4

本系列文章專注於 Gunicorn (WSGI),適合:

  • 維護現有的 Django 專案
  • 學習 WSGI 服務器的工作原理
  • 理解 Workers 的核心概念(也適用於 ASGI)

🎯 本篇重點

理解為什麼 Django 自帶的 runserver 不夠用,必須要用生產級服務器(Gunicorn 或 Uvicorn)。


❌ Django runserver 的問題

問題 1:一次只能處理一個請求

# views.py
import time

def slow_view(request):
    time.sleep(5)  # 模擬慢速處理(例如:複雜計算)
    return HttpResponse("Done!")

情境:3 個用戶同時訪問

Timeline:
0秒  → 用戶 A 訪問 /slow/  開始處理...
1秒  → 用戶 B 訪問 /slow/  ❌ 等待中...
2秒  → 用戶 C 訪問 /slow/  ❌ 等待中...
5秒  → 用戶 A 收到回應
5秒  → 用戶 B 開始處理...
10秒 → 用戶 B 收到回應
10秒 → 用戶 C 開始處理...
15秒 → 用戶 C 收到回應

總共花了 15 秒!

用戶 B 和 C 的感受: 😤 網站怎麼這麼慢!


問題 2:容易崩潰

# views.py
def buggy_view(request):
    result = 1 / 0  # 💥 程式錯誤!
    return HttpResponse(result)

發生什麼事:

用戶訪問 /buggy/
↓
ZeroDivisionError: division by zero
↓
💥 整個 Django runserver 當掉!
↓
所有用戶都無法訪問網站

結果: 網站掛了,必須手動重啟。


問題 3:不安全

Django 官方文檔的警告:

⚠️ DO NOT USE THIS SERVER IN A PRODUCTION SETTING.
   It has not gone through security audits or performance tests.

翻譯: 千萬別在正式網站用,它沒有經過安全檢查!

可能的問題:

  • 容易受到 DDoS 攻擊
  • 沒有請求超時機制
  • 記憶體管理不佳
  • 容易洩漏敏感訊息

問題 4:效能差

# 壓力測試
ab -n 1000 -c 10 http://localhost:8000/

# runserver 結果:
# Requests per second: 50 [#/sec]  ← 一秒處理 50 個請求

# Gunicorn 結果:
# Requests per second: 800 [#/sec]  ← 一秒處理 800 個請求

差距: Gunicorn 快了 16 倍!


✅ Gunicorn 如何解決這些問題

解決 1:多個 Workers 同時處理

gunicorn myproject.wsgi:application --workers 4

同樣的情境:3 個用戶同時訪問

Timeline:
0秒  → 用戶 A 訪問 /slow/  Worker 1 處理...
1秒  → 用戶 B 訪問 /slow/  Worker 2 處理...
2秒  → 用戶 C 訪問 /slow/  Worker 3 處理...
5秒  → 用戶 A 收到回應 ✅
6秒  → 用戶 B 收到回應 ✅
7秒  → 用戶 C 收到回應 ✅

總共花了 7 秒!(原本要 15 秒)

用戶感受: 😊 速度還不錯!


解決 2:Worker 掛了會自動重啟

Worker 2 遇到錯誤 💥
↓
Gunicorn Master: "Worker 2 掛了!"
↓
立即啟動新的 Worker 2'
↓
其他 Workers 繼續正常運作
↓
網站依然可用!✅

視覺化:

Master Process (監工)
├── Worker 1 ✅ 正常運作
├── Worker 2 💥 掛了
│   └── Worker 2' ✅ 自動重啟
├── Worker 3 ✅ 正常運作
└── Worker 4 ✅ 正常運作

解決 3:經過安全審查

Gunicorn 的安全特性:

# gunicorn_config.py
timeout = 30              # 請求超過 30 秒就終止
worker_connections = 1000 # 限制單個 worker 的連接數
max_requests = 1000       # 處理 1000 個請求後重啟(防止記憶體洩漏)
limit_request_line = 4094 # 限制請求行長度(防止攻擊)

結果: 更安全,不容易被攻擊。


解決 4:高效能

Django runserver:
┌──────────┐
│ 1 個進程 │ → 一次處理 1 個請求
└──────────┘

Gunicorn (4 workers):
┌──────────┐
│ Worker 1 │ → 處理請求 A
├──────────┤
│ Worker 2 │ → 處理請求 B
├──────────┤
│ Worker 3 │ → 處理請求 C
├──────────┤
│ Worker 4 │ → 處理請求 D
└──────────┘

效能提升 4 倍以上!

🏗️ 完整的生產環境架構

只用 Django runserver(❌ 錯誤)

用戶 → Django runserver → 資料庫

問題:

  • 沒有負載均衡
  • 沒有靜態文件處理
  • 沒有 HTTPS
  • 效能差

正確的生產環境(✅ 推薦)

用戶
  ↓
Nginx (反向代理 + 靜態文件)
  ↓
Gunicorn (處理 Django 請求)
  ├── Worker 1
  ├── Worker 2
  ├── Worker 3
  └── Worker 4
  ↓
Django Application
  ↓
PostgreSQL/MySQL (資料庫)

每一層的作用:

層級作用比喻
Nginx接收請求、處理靜態文件、HTTPS大門保安
Gunicorn管理 Workers、處理動態請求餐廳經理
Django業務邏輯、資料處理廚房
資料庫儲存資料倉庫

📊 對比總結

特性Django runserverGunicorn
並發處理❌ 一次一個✅ 多個 Workers
穩定性❌ 容易崩潰✅ 自動重啟
安全性❌ 未通過審查✅ 經過安全審查
效能❌ 50 req/sec✅ 800+ req/sec
適用場景✅ 開發環境✅ 生產環境
使用難度⭐ 超簡單⭐⭐ 簡單

💡 實際案例

案例:小型部落格網站

狀況:

  • 每天 1,000 個訪客
  • 使用 Django runserver

問題:

高峰時段(晚上 8-10 點):
- 同時 50 個用戶訪問
- runserver 一次只能處理 1 個
- 用戶等待時間:30-60 秒
- 結果:用戶流失

改用 Gunicorn:

gunicorn myblog.wsgi:application --workers 4

改善結果:

  • 同時可以處理 4 個請求
  • 用戶等待時間:< 2 秒
  • 用戶滿意度提升 ✅

案例:電商網站

狀況:

  • 促銷活動,同時 500 人搶購
  • 使用 Django runserver

災難:

活動開始:
→ 500 個請求湧入
→ runserver 處理第 1 個請求
→ 其他 499 個請求超時
→ 用戶看到錯誤頁面
→ 商機流失!💸

改用 Gunicorn + 優化:

gunicorn myshop.wsgi:application \
    --workers 8 \
    --worker-class gevent \
    --worker-connections 1000

結果:

  • 同時處理 8,000 個連接
  • 活動順利進行 ✅
  • 營收大增 💰

🎤 面試常見問題

Q1: 為什麼不能用 Django runserver 在生產環境?

完整答案:

Django runserver 有四個主要問題:

  1. 單線程:一次只能處理一個請求,無法應對並發流量
  2. 不穩定:遇到錯誤容易整個崩潰,沒有自動恢復機制
  3. 不安全:沒有經過安全審查,容易受到攻擊
  4. 效能差:沒有優化,處理速度遠不及專業的 WSGI Server

因此生產環境必須使用像 Gunicorn 這樣經過考驗的 WSGI Server。


Q2: Gunicorn 解決了什麼問題?

完整答案:

Gunicorn 主要解決了四個問題:

  1. 並發處理:透過多個 worker 進程同時處理多個請求
  2. 高可用性:worker 崩潰時自動重啟,保證服務持續運作
  3. 安全性:提供請求超時、連接限制等安全機制
  4. 高效能:經過優化,效能遠超 Django runserver

這些特性使 Gunicorn 成為生產環境的標準選擇。


Q3: 生產環境的完整架構是什麼?

完整答案:

典型的 Django 生產環境架構從外到內是:

  1. Nginx:反向代理、處理靜態文件、SSL/TLS
  2. Gunicorn:WSGI Server,管理 worker 進程
  3. Django:應用程式,處理業務邏輯
  4. 資料庫:PostgreSQL 或 MySQL,儲存資料
  5. Redis/Celery(可選):快取和異步任務

這樣的分層架構可以充分發揮各組件的優勢,提供穩定高效的服務。


✅ 重點回顧

Django runserver 的問題

  1. ❌ 單線程,無法並發
  2. ❌ 容易崩潰
  3. ❌ 不安全
  4. ❌ 效能差

Gunicorn 的優勢

  1. ✅ 多 Workers 並發處理
  2. ✅ 自動重啟機制
  3. ✅ 安全可靠
  4. ✅ 高效能

何時使用

  • 開發環境:Django runserver(方便快速)
  • 生產環境:Gunicorn(穩定可靠)

📚 接下來

現在你知道為什麼需要 Gunicorn 了!下一篇我們會學:

01-3. Worker 的概念

  • Worker 到底是什麼?
  • Worker 是進程還是線程?
  • Master Process 的作用

🤓 小測驗

  1. Django runserver 最大的問題是什麼?

  2. Gunicorn 如何解決崩潰問題?

  3. 生產環境的標準架構有哪些層級?

  4. 什麼情況下可以用 Django runserver?


上一篇: 01-1. Gunicorn 是什麼
下一篇: 01-3. Worker 的概念


最後更新:2025-10-30

0%