Python WSGI vs ASGI
在 Python 網頁開發的世界裡,你可能常聽到 WSGI 和 ASGI 這兩個術語。它們不是網頁框架 (Web Framework),也不是網頁伺服器 (Web Server),而是介於兩者之間的標準介面 (Interface)。
本文將帶你了解它們是什麼,以及它們如何運作。
為什麼需要介面規範?
早期的 Python 網頁應用程式部屬非常混亂,因為每個網頁框架(如 Django, Flask)都有自己獨特的方式與網頁伺服器(如 Apache, Nginx)溝通。這導致了如果改變網頁伺服器,可能就需要大幅修改程式碼。
為了這決這個問題,Python 社群制定了標準介面規範,讓網頁伺服器和網頁框架解耦:
- 網頁伺服器 (Web Server):如 Nginx, Apache, Gunicorn, Uvicorn。負責處理 HTTP 連線。
- 介面規範 (Interface/Gateway):WSGI 或 ASGI。
- 網頁框架 (Web Framework):如 Django, Flask, FastAPI。負責應用程式邏輯。
WSGI (Web Server Gateway Interface)
WSGI (讀作 "Whiz-ghee") 是 Python 最早也是最廣泛使用的標準介面,定義於 PEP 3333。
特點
- 同步 (Synchronous):WSGI 本質上是同步的。這意味著每個請求都會佔用一個執行緒 (Thread) 或行程 (Process),直到請求處理完成為止。
- 請求/回應模型:它非常適合傳統的 HTTP 請求/回應週期(例如:使用者請求頁面 -> 伺服器回傳 HTML)。
- 限制:由於其同步特性,WSGI 不擅長處理長連線 (Long-polling)、WebSockets 或 HTTP/2,因為這些技術需要長時間保持連線,會導致執行緒耗盡。
常見組合
- 伺服器:Gunicorn, uWSGI
- 框架:Django, Flask, Pyramid, Bottle
運作原理 (簡化版)
WSGI 應用程式只是一個 Python 函式 (Callable),它接收兩個參數:environ (環境變數字典) 和 start_response (回傳回應標頭的函式)。
def application(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [b"Hello World"]
ASGI (Asynchronous Server Gateway Interface)
隨著現代網頁技術的發展,對於即時性 (Real-time) 和高併發 (High Concurrency) 的需求越來越高。WSGI 的同步限制成為了瓶頸,因此 ASGI 應運而生。
特點
- 非同步 (Asynchronous):ASGI 原生支援
async/await語法。它可以處理大量的併發連線,而不需要為每個連線開啟一個新的執行緒。 - 強大的功能:除了標準的 HTTP 請求,ASGI 還原生支援 WebSockets 和 HTTP/2 等通訊協定。
- 向後相容:許多 ASGI 伺服器也支援執行傳統的 WSGI 應用程式。
常見組合
- 伺服器:Uvicorn, Daphne, Hypercorn
- 框架:FastAPI, Django (透過 Channels), Quart, Starlette
運作原理 (簡化版)
ASGI 應用程式也是一個 Callable,但它是非同步的,並接收三個參數:scope (連線資訊), receive (接收事件), send (發送事件)。
async def application(scope, receive, send):
assert scope['type'] == 'http'
await send({
'type': 'http.response.start',
'status': 200,
'headers': [[b'content-type', b'text/plain']],
})
await send({
'type': 'http.response.body',
'body': b'Hello World',
})
比較總結
| 特性 | WSGI | ASGI |
|---|---|---|
| 全名 | Web Server Gateway Interface | Asynchronous Server Gateway Interface |
| 執行模式 | 同步 (Synchronous) | 非同步 (Asynchronous) |
| 適用場景 | 標準 CRUD 應用、傳統網頁 | 即時聊天、WebSocket、高併發 API |
| WebSockets | 不支援 (或需額外 hack) | 原生支援 |
| 代表框架 | Flask, Django (傳統) | FastAPI, Django Channels |
| 代表伺服器 | Gunicorn, uWSGI | Uvicorn, Daphne |
該選哪一個?
- 選擇 ASGI:如果你要開發一個全新的 API 服務,或者需要使用 WebSockets、即時通知等功能,FastAPI + Uvicorn (ASGI) 是現代 Python 開發的首選。它的效能通常比 WSGI 更好。
- 選擇 WSGI:如果你正在維護一個既有的 Django 或 Flask 專案,且沒有特別的高併發或 WebSocket 需求,WSGI 仍然非常穩定且可靠。不需要為了追求新技術而盲目遷移。