探討 NGINX 的 HTTP 核心模組設定,從網路層的 socket 監聽與虛擬主機組態,到應用層的 HTTP 請求處理與資源管理,涵蓋了 listen 指令的地址、埠與進階選項設定,server_name 指令的多網域名稱與萬用字元設定,以及 rootalias 指令的檔案路徑管理。此外,也詳細說明瞭錯誤頁面 error_page 的設定技巧、檔案傳輸最佳化 sendfile 的使用方式、客戶端連線管理 keepalive 的設定、以及 try_files 指令的動態檔案查詢機制。這些指令的正確組態能有效提升網站伺服器的穩定性、安全性與效能。

必要注意事項

本檔案適用於穩定版本 1.25。未來更新可能會更改某些指令的語法或提供本文未討論的新功能。

Socket 和主機組態

這組指令將允許我們組態虛擬主機,實際上是透過建立 server 塊來識別主機名或 IP 地址和埠組合。此外,一些指令將讓我們精細調整網路設定並組態 TCP socket 選項。

listen

上下文:server

規範要使用監聽 socket 的 IP 地址和/或埠來服務網站。網站通常透過埠 80(預設值)透過 HTTP 或埠 443 透過 HTTPS 提供服務。

語法:listen [address][:port] [其他選項];

其他選項包括:

  • default_server:規範此 server 塊應作為特定 IP 地址和埠接收到任何請求時使用之預設網站。
  • ssl:規範網站應使用 SSL 提供。
  • http2:啟用對 HTTP/2 協定支援(如果 http2 模組存在)。
  • proxy_protocol:啟用 proxy 協定對於此埠接受之所有連線。
  • 其他選項與 bind 和 listen 系統呼叫相關:backlog=num, rcvbuf=size, sndbuf=size, accept_filter=filter, deferred, setfib=number, fastopen=number, ipv6only=on|off, reuseport, so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt], bind, http2
listen 192.168.1.1:80;
listen 127.0.0.1;
listen 80 default_server;
listen [:::a8c9:1234]:80; # IPv6 地址必須放在方括號內
listen 443 ssl http2;

listen 指令詳細解說:

listen [address][:port] [additional options];
內容解密:
  • address:可選引數,表示監聽 IP 地址。
  • port:可選引數,表示監聽埠號碼。
  • additional options:其他可選引數來進一步組態監聽行為。
    • default_server:當沒有其他比對時使用此 server 塊作為預設。
    • ssl:啟用 SSL 加密。
    • http2:啟用 HTTP/2 支援。
    • proxy_protocol:啟用 Proxy Protocol。
    • 其他引數:如 backlog、rcvbuf、sndbuf、accept_filter、deferred、setfib、fastopen、ipv6only、reuseport、so_keepalive。
listen 80 default_server; # 預設監聽埠
listen [::]:443 ssl; # IPv6 地址和 SSL 加密

以上就是 NGINX 組態中最基本且重要的一些概念及其相關細節說明。

NGINX HTTP 模組指令探討

伺服器名稱與請求處理

伺服器名稱指令(server_name)

在 NGINX 中,server_name 指令用於指定一個或多個伺服器區塊的主機名稱。當 NGINX 接收到 HTTP 請求時,會將請求的 Host 頭部與所有伺服器區塊進行比對。首先比對成功的伺服器區塊將被選中處理請求。

如果沒有任何伺服器區塊比對請求的主機名稱,NGINX 將選擇第一個比對 listen 指令引數(例如 listen *:80)的伺服器區塊,並優先考慮啟用 default_server 選項的區塊。

此指令接受萬用字元和正規表示式,萬用字元主機名稱需以 ~ 字元開頭。以下是一些範例:

  • server_name www.website.com;
  • server_name www.website.com website.com;
  • server_name *.website.com;
  • server_name .website.com; (組合 *.website.comwebsite.com
  • server_name *.website.*;
  • server_name ~^(www)\.example\.com$; (捕捉群組 $1 = www

此外,可以使用空字串來捕捉沒有 Host 頭部的請求,但這必須在至少一個正常名稱(或使用 _ 作為佔位符)後使用:

  • server_name website.com "";
  • server_name _ "";

重定向中的伺服器名稱(server_name_in_redirect)

此指令適用於內部重定向。如果設為 on,NGINX 將使用在 server_name 指令中指定的第一個主機名稱。如果設為 off,NGINX 將使用 HTTP 請求中的 Host 頭部值。

  • 語法:onoff
  • 預設值:off

伺服器名稱雜湊表設定

伺服器名稱雜湊表最大大小(server_names_hash_max_size)

NGINX 使用雜湊表來加速請求處理。此指令定義了伺服器名稱雜湊表的最大大小。預設值應該滿足大部分組態需求,如果需要更改,NGINX 會在啟動或重新載入組態時提示。

  • 語法:數值
  • 預設值:512

伺服器名稱雜湊桶大小(server_names_hash_bucket_size)

此指令設定伺服器名稱雜湊表的桶大小。只有在 NGINX 提示需要時才應更改此值。

  • 語法:數值
  • 預設值:32 或 64 或 128(視 CPU 暫存規格而定)

HTTP 請求重定向

重定向中包含埠號(port_in_redirect)

如果停用此指令,NGINX 發行的重定向將是相對路徑。

  • 語法:onoff
  • 預設值:on

絕對重定向(absolute_redirect)

此指令決定在重定向時是否附加埠號到重定向 URL 中。

  • 語法:onoff
  • 預設值:on

檔案傳輸最佳化

檔案傳輸方法(sendfile)

啟用此指令後,NGINX 將使用核心呼叫 sendfile 來處理檔案傳輸。停用後,NGINX 自行處理檔案傳輸。這個選項可能會影響伺服器效能,特別是檔案位於 NFS 的情況下。

在 Linux 上,啟用 sendfile 會自動停用非同步 I/O。在 FreeBSD 上,可以同時使用 aio 和 sendfile。

  • 語法:onoff
  • 預設值:off
http {
    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/html;
            sendfile on;
        }
    }
}

傳輸片段大小(sendfile_max_chunk)

此指令定義每次呼叫 sendfile 的最大資料大小。

  • 語法:數值(大小)
  • 預設值:0
http {
    sendfile_max_chunk 1m;
}

SO_SNDLOWAT 標誌設定(send_lowat)

此指令僅適用於 FreeBSD ,用於設定 TCP 接收通訊端的輸出緩衝區最小位元組數。

http {
    send_lowat 1k;
}

與客戶端連線相關設定

超時連線重置(reset_timedout_connection)

啟用此指令後,當客戶端連線超時時,其相關資訊將被清除並從記憶體中移除。

http {
    server {
        listen 80;
        server_name example.com;

        location / {
            reset_timedout_connection on;
        }
    }
}

路徑與檔案組態

網站檔案根目錄與索引檔案設定

路徑根目錄設定(root)

此指令定義要提供給訪客的檔案根目錄路徑。變數可以接受 root 指令中進行動態調整根目錄位置。

http {
    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/html;
        }
    }
}

資源別名組態(alias)

別名設定僅能放置在 location 塊內。它為特定要求提供一個不同的路徑來取得檔案。例如:

http {
    server {
        server_name localhost;
        root /var/www/website.com/html;

        location /admin/ {
            alias /var/www/locked/;
        }
    }
}

在此範例中,當收到對 http://localhost/admin/ 的請求時,實際路徑將被轉換為 /var/www/locked/ ,而不影響原始的 document root 路徑。

錯誤頁面處理

錯誤頁面設定(error_page)

此指令允許將 URI 指派給 HTTP 回應碼並可選地替換程式碼為另一程式碼。以下是語法說明:

error_page code1 [code2...] [=replacement code] [=@block | URI]

其中替換程式碼 (以 =code 命名) 必須是以下之一:301、302、303、307 或 308。

以下是實際範例:

error_page   404              /404.html;
error_page   500 502 503 504  /50x.html;
error_page   499              =@fallback;

location = /40x.html {
    internal;
}

location = /50x.html {
    internal;
}

location @fallback {
    proxy_pass http://backend;
}

在這個例子中:

  • 出現404錯誤時會顯示 /404.html
  • 出現5XX錯誤時會顯示 /50x.html
  • 出現499錯誤時則會跳轉至 @fallback

機制圖解

以下圖示展示了 NGINX 處理HTTP請求流程:

  graph TD
A[接收HTTP請求] --> B{查詢Host頭部}
B -- 比對成功 --> C[選擇伺服器區塊]
B -- 無比對 --> D[選擇預設區塊]
C --> E[傳送回應]
D --> E[傳送回應]

次段落標題

小段落標題

這圖示展示了 NGINX 接收HTTP請求後如何根據Host頭部來查詢適合的伺服器區塊以傳送回應。

活用 NGINX 基本模組進行高效HTTP請求處理與資源管理

NGINX HTTP Core 模組指令探討

NGINX 是一個強大的網頁伺服器,其 HTTP Core 模組提供了許多關鍵指令,用於組態和管理伺服器行為。這些指令涵蓋了從錯誤處理到客戶端請求管理的各個方面。以下是一些重要的 NGINX HTTP Core 模組指令及其應用。

錯誤頁面處理

錯誤頁面處理是伺服器組態中的一個關鍵部分,它確保當客戶端請求出錯時,伺服器能夠提供適當的回應。error_page 指令用於定義特定 HTTP 狀態碼時應該傳回的頁面。

error_page 404 /not_found.html;
error_page 500 501 502 503 504 /server_error.html;

內容解密:

  • error_page 指令用於設定特定 HTTP 狀態碼時的錯誤頁面。例如,當客戶端請求的資源不存在時(狀態碼 404),伺服器會傳回 not_found.html 頁面。
  • error_page 支援多種狀態碼,並且可以設定多個錯誤頁面。這樣可以根據不同的錯誤型別提供不同的錯誤頁面。

If-Modified-Since 處理

if_modified_since 指令定義了 NGINX 如何處理 If-Modified-Since HTTP 頭部。這個頭部主要由搜尋引擎爬蟲使用,以避免重複下載未變更的資源。

if_modified_since exact;

內容解密:

  • if_modified_since 指令有三個值可選:offexactbefore
    • off: 忽略 If-Modified-Since 頭部。
    • exact: 若頭部中的日期與資源的最後修改時間完全比對,則傳回 304 Not Modified。
    • before: 若頭部中的日期早於或等於資源的最後修改時間,則傳回 304 Not Modified。
  • 預設值為 exact,這意味著只有當頭部中的日期與資源的最後修改時間完全比對時,才會傳回 304 Not Modified。

預設首頁設定

index 指令用於定義當客戶端請求目錄而沒有指定具體檔案時,伺服器應該傳回的預設首頁。

index index.php index.html index.htm;

內容解密:

  • index 指令可以設定多個預設檔名稱,伺服器會依次檢查這些檔案是否存在,並傳回第一個找到的檔案。
  • 若所有指定的檔案都不存在,則根據 autoindex 指令的設定來決定是生成自動索引還是傳回 403 Forbidden 錯誤頁面。
  • 預設值為 index.html

處理巢狀錯誤頁面

有時候,錯誤頁面本身可能會引發錯誤。為了處理這種情況,NGINX 提供了 recursive_error_pages 指令來啟用或停用巢狀錯誤頁面。

recursive_error_pages on;

內容解密:

  • recursive_error_pages 指令可以設定為 onoff
  • 預設值為 off,即停用巢狀錯誤頁面。
  • 啟用此功能後,當錯誤頁面本身引發錯誤時,NGINX 會再次使用 error_page 指令來處理該錯誤。

動態檔案查詢

try_files 指令用於嘗試服務一系列檔案,如果所有檔案都不存在,則轉發到指定的位置或 URI。

location / {
    try_files $uri $uri.html $uri.xml @proxy;
}

location @proxy {
    proxy_pass 127.0.0.1:8080;
}

內容解密:

  • try_files 指令會依次嘗試服務列出的檔案。如果所有檔案都不存在,則轉發到最後一個引數指定的位置或 URI。
  • 在上例中,NGINX 首先嘗試服務 $uri 對應的檔案。若不存在,則嘗試 $uri.html$uri.xml。若仍不存在,則轉發到 @proxy 名稱位置。
  • @proxy 是一個命名位置區塊(named location block),其中包含了轉發規則。

Keep-Alive 機制

Keep-Alive 機制允許在一個 TCP 連線中傳輸多個 HTTP 請求和回應,從而減少連線建立和關閉所需的時間。

keepalive_requests 100;
keepalive_timeout 75;
keepalive_disable msie6;

內容解密:

  • keepalive_requests: 用於設定單個 Keep-Alive 連線中允許的最大請求數量。預設為 100。
  • keepalive_timeout: 用於設定伺服器在關閉 Keep-Alive 連線之前等待多長時間。預設為 75秒。第二個引數是傳遞給客戶端瀏覽器的 Keep-Alive 頭部值。
  • keepalive_disable: 用於停用特定瀏覽器家族(如 IE6)的 Keep-Alive 功能。

其他客戶端請求組態

除了 Keep-Alive 機制外,NGINX 提供了一些其他指令來管理客戶端請求行為:

send_timeout 60;
client_body_in_file_only clean;
client_body_in_single_buffer off;

內容解密:

  • send_timeout: 用於設定在不活動狀態下 NGINX 在關閉連線之前等待多長時間。預設為60秒。
  • client_body_in_file_only: 用於控制是否將 HTTP 請求體儲存在磁碟上。可選值為 off, clean, 和 on
    • off: 不將請求體儲存在檔案中
    • clean: 請求處理後刪除檔案
    • on: 請求處理後保留檔案
    • 預設為 off
  • client_body_in_single_buffer: 用於控制是否將請求體儲存在單一緩衝區中。預設為 off。

透過這些指令和組態專案,NGINX 能夠靈活地處理各種客戶端請求和錯誤情況,從而提高伺服器的穩定性和效能。