探討 NGINX 的 HTTP 核心模組設定,從網路層的 socket 監聽與虛擬主機組態,到應用層的 HTTP 請求處理與資源管理,涵蓋了 listen 指令的地址、埠與進階選項設定,server_name 指令的多網域名稱與萬用字元設定,以及 root、alias 指令的檔案路徑管理。此外,也詳細說明瞭錯誤頁面 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.com和website.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 頭部值。
- 語法:
on或off - 預設值:
off
伺服器名稱雜湊表設定
伺服器名稱雜湊表最大大小(server_names_hash_max_size)
NGINX 使用雜湊表來加速請求處理。此指令定義了伺服器名稱雜湊表的最大大小。預設值應該滿足大部分組態需求,如果需要更改,NGINX 會在啟動或重新載入組態時提示。
- 語法:數值
- 預設值:512
伺服器名稱雜湊桶大小(server_names_hash_bucket_size)
此指令設定伺服器名稱雜湊表的桶大小。只有在 NGINX 提示需要時才應更改此值。
- 語法:數值
- 預設值:32 或 64 或 128(視 CPU 暫存規格而定)
HTTP 請求重定向
重定向中包含埠號(port_in_redirect)
如果停用此指令,NGINX 發行的重定向將是相對路徑。
- 語法:
on或off - 預設值:
on
絕對重定向(absolute_redirect)
此指令決定在重定向時是否附加埠號到重定向 URL 中。
- 語法:
on或off - 預設值:
on
檔案傳輸最佳化
檔案傳輸方法(sendfile)
啟用此指令後,NGINX 將使用核心呼叫 sendfile 來處理檔案傳輸。停用後,NGINX 自行處理檔案傳輸。這個選項可能會影響伺服器效能,特別是檔案位於 NFS 的情況下。
在 Linux 上,啟用 sendfile 會自動停用非同步 I/O。在 FreeBSD 上,可以同時使用 aio 和 sendfile。
- 語法:
on或off - 預設值:
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指令有三個值可選:off、exact和before。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指令可以設定為on或off。- 預設值為
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, 和onoff: 不將請求體儲存在檔案中clean: 請求處理後刪除檔案on: 請求處理後保留檔案- 預設為 off
client_body_in_single_buffer: 用於控制是否將請求體儲存在單一緩衝區中。預設為 off。
透過這些指令和組態專案,NGINX 能夠靈活地處理各種客戶端請求和錯誤情況,從而提高伺服器的穩定性和效能。