NGINX 作為廣泛使用的 Web 伺服器和反向代理伺服器,其效能調校至關重要。本文著重於 events 模組的設定,講解如何調整 worker 程式數量、連線限制、事件模型等關鍵引數,以最佳化 NGINX 的網路處理能力。同時,文章也涵蓋了組態模組的運用,例如使用 include 指令引入外部設定檔,簡化組態管理並提升可讀性。此外,文章也提供了一些必要的調整建議,例如設定 user 指令以提升安全性,以及調整 worker_processesworker_priority 指令以最佳化資源利用率。透過理解這些核心指令的設定技巧,可以有效提升 NGINX 的效能和穩定性,滿足高流量網站的需求。

NGINX 基礎組態

NGINX 是一個高效且強大的 Web 伺服器和反向代理伺服器,其組態檔案中包含多個模組,每個模組都有特定的指令來調整系統效能。以下將探討 events 模組和組態模組的關鍵指令,並提供實際應用的建議。

events 模組

events 模組負責組態網路機制,這些組態對應用程式的效能有著重要影響。所有 events 模組的指令必須放在 events 塊中,該塊位於組態檔案的根目錄。

user nginx nginx;
master_process on;
worker_processes 4;
events {
    worker_connections 1024;
    use epoll;
}

以下是一些關鍵的 events 模組指令及其說明:

accept_mutex

  • 語法與說明accept_mutex on;accept_mutex off;
  • 預設值:自 1.11.3 版本起為 off,之前版本為 on
  • 作用:啟用或停用接受互斥鎖(mutual exclusion),以開啟監聽通訊端。

accept_mutex_delay

  • 語法與說明accept_mutex_delay 500ms;
  • 預設值:500 毫秒。
  • 作用:定義 worker 程式在重新嘗試取得資源前等待的時間。若 accept_mutex 指令設為 off,則不使用此值。

debug_connection

  • 語法與說明debug_connection 172.63.155.21;debug_connection 172.63.155.0/24;
  • 預設值:無。
  • 作用:為比對該 IP 地址或地址區塊的客戶端寫詳細日誌。除錯資訊儲存在 error_log 指令指定的檔案中,並以除錯級別啟用。

multi_accept

  • 語法與說明multi_accept off;
  • 預設值off
  • 作用:定義 NGINX 是否應一次接受監聽佇列中的所有傳入連線。

use

  • 語法與說明use kqueue;
  • 預設值:編譯時定義。
  • 作用:選擇可用的事件模型(編譯時啟用的那些)。NGINX 會自動選擇最合適的一個,通常不需要修改此值。

可用的事件模型包括:

  • select:標準模組,適用於不支援更高效方法的作業系統(如 Windows)。
  • poll:比 select 高效,但不在所有系統上可用。
  • kqueue:適用於 FreeBSD、OpenBSD、NetBSD 和 macOS。
  • epoll:適用於 Linux 2.6+ 系統。
  • /dev/poll:適用於 Solaris、HP/UX、IRIX 和 Tru64 UNIX 等系統。

worker_connections

  • 語法與說明worker_connections 1024;
  • 預設值:無。
  • 作用:定義一個 worker 程式可以同時處理的連線數量。

組態模組

NGINX 的組態模組允許透過 include 指令包含其他組態檔案。該指令可以插入到組態檔案的任何位置,並接受一個引數——檔案路徑。

include /file/path.conf;
include sites/*.conf;

若未指定絕對路徑,則路徑相對於組態目錄。例如,預設情況下,include sites/example.conf; 會包含 /usr/local/nginx/conf/sites/example.conf 檔案。

必要調整

在初次設定 NGINX 時,需要仔細調整一些核心指令:

user 指令

user www-data www-data;

這個指令指定 worker 程式以 root 身份啟動,這樣做會帶來安全風險。建議建立一個新的使用者帳戶並使用它來執行 NGINX。

worker_processes 指令

worker_processes auto;

這個指令定義啟動的 worker 程式數量。預設值為 1,意味著所有請求都由單一執行流程處理。建議根據 CPU 槽位數量設定此值或設定為 auto 以讓 NGINX 自動決定最佳值。

worker_priority 指令

worker_priority -5;

這個指令設定 worker 程式的優先順序。如果系統同時執行其他任務,可以考慮提高 NGINX worker 程式的優先順序。優先順序範圍從 -20(最高優先順序)到 19(最低優先順序),不建議設定低於 -5 的值。

NGINX 伺服器組態與測試

NGINX 是一個高效的 Web 伺服器和反向代理伺服器,具備強大的組態靈活性。本文將探討 NGINX 的基本組態與測試方法,並提供實務案例及詳細解說,幫助讀者更好地理解和應用 NGINX。

基本組態指令

在開始之前,我們先來看看一些基本的組態指令:

log_not_found on;
worker_connections 1024;

內容解密:

  • log_not_found on;:這個指令會記錄所有的 404 錯誤,這些錯誤可能是因為瀏覽器試圖存取 favicon 或爬蟲試圖存取 robots.txt 檔案而產生的。如果不想讓日誌檔案被這些錯誤資訊佔據,可以將其設為 off。但要注意,這樣做可能會遺漏一些有價值的存取錯誤資訊。
  • worker_connections 1024;:這個設定結合 worker 程式數量來定義伺服器同時接受的連線數量。假設啟用了四個 worker 程式,每個程式接受 1,024 個連線,則伺服器可以同時處理 4,096 個連線。需要根據硬體資源(如 RAM 和 CPU)來調整這個設定。

測試你的伺服器

接下來,我們將實際操作測試這些組態指令,並啟動測試伺服器來觀察 NGINX 的行為。

建立測試伺服器

要進行基本的測試,例如使用瀏覽器連線到伺服器,我們需要設定一個網站供 NGINX 提供服務。預設安裝包中已經包含了一個測試頁面,位於 /usr/local/nginx/html/index.html。原始的 nginx.conf 已經組態好來提供這個頁面。以下是我們感興趣的部分:

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    server {
        listen 80;
        server_name localhost;

        location / {
            root html;
            index index.html index.htm;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }
}
  graph TD;
    A[HTTP Block] --> B[Include MIME Types];
    A --> C[Default Type];
    A --> D[Sendfile On];
    A --> E[Keepalive Timeout];
    A --> F[Server Block];
    F --> G[Listen on Port 80];
    F --> H[Server Name: localhost];
    F --> I[Location Block];
    I --> J[Root Directory: html];
    I --> K[Index Files: index.html, index.htm];

內容解密:

  • http { ... }:這是 HTTP 塊,包含了所有與 HTTP 組態相關的指令。
  • include mime.types;:包含 MIME 型別定義檔案,用於正確解釋不同型別的檔案。
  • default_type application/octet-stream;:設定預設的 MIME 型別。
  • sendfile on;:啟用高效檔案傳輸。
  • keepalive_timeout 65;:設定保持連線的超時時間。
  • server { ... }:這是伺服器塊,包含了與特定網站相關的組態。
  • listen 80;:監聽埠號為 80。
  • server_name localhost;:設定伺服器名稱為 localhost。
  • location / { ... }:這是位置塊,定義瞭如何處理根路徑 / 的請求。
  • root html;:設定根目錄為 /usr/local/nginx/html
  • index index.html index.htm;:設定索引檔案為 index.htmlindex.htm
  • error_page 500 502 503 504 /50x.html;:設定錯誤頁面。
  • location = /50x.html { ... }:定義了錯誤頁面的位置塊。

測試步驟

啟動你喜歡的網頁瀏覽器並存取 http://localhost/。你應該會看到一條歡迎資訊。如果沒有看到,請檢查組態並重新載入 NGINX。

無縫升級 NGINX

在某些情況下,你可能需要替換 NGINX 二進位制檔案(例如升級到新版本或啟用新模組)。傳統做法是停止伺服器、替換二進位制檔案,然後重新啟動 NGINX。雖然對大多數網站來說這不是問題,但對於需要保持高用性和零丟失連線的情況來說,這可能會造成麻煩。

幸運的是,NGINX 提供了一個機制來在不中斷服務的情況下升級二進位制檔案。以下是具體步驟:

  1. 用新二進位制檔案替換舊的 NGINX 二進位制檔案(預設位於 /usr/local/nginx/sbin/nginx)。
  2. 查詢 NGINX 主程式的 PID(例如使用 ps x | grep nginx | grep master 或檢視 .pid 檔案)。
  3. 對主程式傳送 USR2 (12) 命令(例如 kill -USR2 <pid>),這將開始升級過程並重新命名舊的 .pid 檔案並執行新二進位制檔案。
  4. 對舊主程式傳送 WINCH (28) 命令(例如 kill -WINCH <pid>),這將優雅地關閉舊工作程式。
  5. 檢查所有舊工作程式是否已終止,然後對舊主程式傳送 QUIT 命令(例如 kill -QUIT <pid>)。

完成以上步驟後,你將成功升級 NGINX 暴露而沒有丟失任何連線。

探索 HTTP 組態

在完成基本組態和測試之後,我們將探討 HTTP 組態模組及其相關指令。

HTTP Core 模組簡介

HTTP Core 模組包含了 HTTP 伺服器所有基本組態區塊、指令和變數。它在預設情況下是啟用的(如第1章所描述),但也可以選擇不包含它以完全停用所有 HTTP 功能。

HTTP Core 模組主要包括三個區塊:

  1. http:包含所有與 HTTP 組態相關的指令。
  2. server:定義特定網站或虛擬主機的組態。
  3. location:定義如何處理特定 URL 路徑。

研究 NGINX 的 HTTP 組態

NGINX 的 HTTP 模組是所有標準模組中最龐大的,提供了大量的指令和變數。為了理解這些新元素及其運作方式,我們首先需要了解由三個主要區塊——http、server 和 location——所引入的邏輯組織架構。

http、server 和 location 三個區塊

在前一章節中,我們透過研究 NGINX 點預設組態檔案來瞭解核心模組,這個檔案包含了一系列看似無序的指令和值。接著,我們介紹了 events 模組,並引入了第一個區塊(events)。這個區塊是 events 模組所帶來的所有指令的唯一容器。

事實上,HTTP 模組引入了三個新的邏輯區塊:

  1. http:這個區塊插入到組態檔案的根目錄。它允許我們開始定義所有與 NGINX 的 HTTP 方面相關的模組中的指令和區塊。雖然沒有真正的必要性,但這個區塊可以多次插入,最後插入的區塊中的指令值將覆寫之前的值。

  2. server:這個區塊允許我們宣告一個網站。換句話說,一個特定的網站(由一個或多個主機名稱識別,例如 www.mywebsite.com)被 NGINX 認識並獲得自己的組態。這個區塊只能在 http 區塊內使用。

  3. location:這個區塊讓我們定義一組應用於網站特定位置的設定。這個區塊可以在 server 區塊內使用,或者巢狀在另一個 location 區塊內。

以下圖示總結了最終結構,並提供了一些基本例子對應實際情況:

此圖示

HTTP 主模組指令

HTTP 區段由 http{...} 區塊定義,涵蓋了整個網頁相關的組態。它可能包含一個或多個 server{...} 區塊,定義了您正在託管的網域名稱和子網域名稱。對於這些網站中的每一個,您有定義 location 區塊的可能性,讓您可以將額外設定應用於特定請求 URI 或比對模式的請求 URI。

請記住,設定繼承原則在此適用。如果在 http{...} 區塊級別定義了一項設定(例如,啟用 gzip 壓縮),該設定將在潛在包含的 server 和 location 區塊中保持其值:

http {
    # 在 http 區塊級別啟用 gzip 壓縮
    gzip on;
    server {
        server_name localhost;
        listen 80;
        # 此階段 gzip 仍設為開啟
        location /downloads/ {
            gzip off;
            # 此指令僅適用於 /downloads/ 中找到的檔案
        }
    }
}

我們已經學習了 NGINX 的區塊結構並以具體例子進行實踐。接下來,我們將探討這三個區塊中可用的模組。

探索 HTTP 主模組指令

在每個級別(前面討論過的區塊)中都可以插入指令以影響 Web 伺服器的行為。以下小節涵蓋了主 HTTP 模組引入的所有指令,按主題分組。對於每條指令,都會給出上下文說明。有些指令在某些級別無法使用。例如,將 server_name 指令插入到 http 區塊級別毫無意義,因為 server_name 是直接影響虛擬主機的一條指令——它應該只插入到 server 區塊中。因此,表格指出每條指令允許使用的可能級別——http 區塊、server 區塊、location 區塊以及額外的 if 區塊。