在高併發伺服器領域,Nginx 之所以能大幅超越傳統的 Apache,關鍵在於其採用的網路 I/O 模型不同。Apache 早期版本主要依賴 select 模型,而 Nginx 則充分利用了 Linux 2.6+ 核心提供的 epoll(以及 FreeBSD 的 kqueue)機制。這不僅是 API 的差異,更是底層處理邏輯的根本變革。
想像一下大學宿舍等朋友的場景:
__FD_SETSIZE 通常為 1024,無法突破單進程監控 1024 個以上的檔案描述符(FD)。/proc/sys/fs/file-max),1GB 記憶體機器輕鬆支撐 10 萬級並發。mmap 將核心態就緒列表映射至用戶態,避免重複拷貝。場景對比:在高速 LAN 內幾乎所有 Socket 都活躍時,epoll 優勢不明顯,甚至因頻繁
epoll_ctl略遜於 select。但一旦模擬 WAN 環境(大量 Idle 連接),epoll 效能碾壓 select/poll 數個數量級。
| 模式 | 全稱 | 特性 | 適用場景 |
|---|---|---|---|
| LT | Level Triggered(電平觸發) | 預設模式;支援 Block/Non-block;就緒狀態持續通知,直到處理完畢;編程容錯率高 | 通用場景、快速原型開發 |
| ET | Edge Triggered(邊緣觸發) | 高速模式;僅支援 Non-block;狀態變化瞬間通知一次,假設開發者會一次性讀寫完畢;若未讀寫至 EWOULDBLOCK,不再通知 |
極致高併發、自定義協議解析 |
Nginx 預設採用 LT 模式保證穩定,但在特定模組(如 ngx_http_v2_module)中會啟用 ET 以榨乾效能。理解兩者差異,是寫出高性能網路程式的必修課。
從 Select 到 Epoll,是從「輪詢思維」到「事件思維」的範式轉移。Nginx、Redis、Kafka 等現代高性能中間件,皆建立於 epoll/kqueue/IOCP 等作業系統級別的異步通知機制之上。掌握其原理,不僅能指導架構選型,更能在排查疑難效能問題時直搗黃龍。