本文將講述如何配置 nginx 提供靜態(tài)內(nèi)容服務(wù)池凄,如何定義文件路徑,以及如何設(shè)置 index 文件狠半。
目錄:
- root 目錄以及 index 文件
- try_file 指令
- 優(yōu)化 nginx 的速度
- 開啟 sendfile
- 開啟 tcp_nopush
- 開啟 tcp_nodelay
- 優(yōu)化 Backlog Queue
- 測量 Listen Queue
- 調(diào)優(yōu)系統(tǒng)參數(shù)
- 調(diào)整 nginx 配置參數(shù)
root 目錄以及 index 文件
root 指令用于指定 nginx 查找文件的基礎(chǔ)路徑,nginx 所提供的文件都在該路徑之下。
nginx 將請求的 URI 追加到 root 指令所指定的路徑之后秽之,形成最終的文件訪問路徑。root 指令可放置于 http吃既、server 以及 location 上下文中考榨。在下面的例子中,root 指令定義在 server 上下文中鹦倚,如果一個 location 沒有自己設(shè)置 root 定義河质,它就從 server 區(qū)塊繼承 root 指令的定義:
server {
root /www/data;
location / {
}
location /images/ {
}
location ~ \.(mp3|mp4) {
root /www/media;
}
}
基于這份配置,如果 URI 以 /images/ 起始震叙,nginx 在 /www/data/images/ 路徑下查找文件掀鹅。但如果 URI 以 .mp3 或 .mp4 為后綴,nginx 會在 /www/media 中查找文件媒楼,這是因為正則表達(dá)式匹配的 location 有更高的優(yōu)先級乐尊。
如果請求以 / 為結(jié)尾,nginx 將其視為對一個目錄的請求划址,并嘗試在該目錄中找到 index 文件扔嵌。index 指令定義了 index 文件的名字(默認(rèn)的名字為 index.html)限府。如果一個請求的 URI 為 /images/some/path/
,nginx 嘗試找到 /www/data/images/some/path/index.html
文件痢缎,并返回給客戶端胁勺。如果該文件不存在,nginx 默認(rèn)返回 404 (Not found) 錯誤牺弄。如果希望這時 nginx 返回一個自動生成的目錄列表而不是返回 404 錯誤姻几,使用 autoindex 指令進(jìn)行設(shè)置:
location /images/ {
autoindex on;
}
在 index 指令中,可設(shè)置多個文件名势告,nginx 根據(jù)設(shè)置的順序依次查找蛇捌,并返回第一個找到的文件:
location / {
index index.$geo.html index.htm index.html;
}
$geo 變量是一個自定義的變量,由 geo 指令所定義咱台。該變量的值依賴于客戶端的IP地址络拌。
當(dāng) nginx 找到 index 文件后,會做一個內(nèi)部重定向回溺,新的 URI 是將 index 文件的文件名追加到原來的 URI 上春贸。進(jìn)行內(nèi)部重定向之后,nginx 對新的 URI 進(jìn)行匹配查找遗遵,下面是一個例子:
location / {
root /data;
index index.html index.php;
}
location ~ \.php {
fastcgi_pass localhost:8000;
...
}
此例中萍恕,如果一個請求的 URI 為 /path/,且 /data/path/index.html
文件不存在车要,但 /data/path/index.php
文件存在允粤,這時,做完內(nèi)部重定向后的新的URI 為 /path/index.php
翼岁,將被第二個 location 所匹配类垫,該請求最終被轉(zhuǎn)發(fā)給后端服務(wù)器。
try_file 指令
try_files 指令用于檢測指定的文件或目錄是否存在琅坡,如果不存在悉患,就做內(nèi)部重定向,或者返回指定的狀態(tài)碼榆俺。
例如售躁,使用 try_files 指令和 $uri 變量可以檢測一個請求的 URI 所對應(yīng)的文件是否存在:
server {
root /www/data;
location /images/ {
try_files $uri /images/default.gif;
}
}
此例中,如果一個請求的 URI 對應(yīng)的文件不存在茴晋,比如 URI 為 /images/somefile.png
迂求,對應(yīng)的文件路徑為 /www/data/images/somefile.png
,如果這個文件不存在晃跺,try_files 指令將原來的 URI 內(nèi)部重定向到 /images/default.gif
揩局,nginx 進(jìn)行重新匹配查找,最后返回 /www/data/images/default.gif
文件掀虎。
try_files 指令的最后一個參數(shù)可以是一個狀態(tài)碼(比如 =404)凌盯,或者是一個 location 的名字付枫。在下面的例子中,如果 try_files 指令的所有參數(shù)都沒有解析為一個存在的文件或目錄驰怎,那么就返回 404 錯誤:
location / {
try_files $uri $uri/ $uri.html =404;
}
在下面的例子中阐滩,如果原始的 URI,以及 URI/ 都不能解析為一個存在的文件或目錄县忌,該請求將被重定向至一個命名的 location掂榔,該 location 將把請求轉(zhuǎn)發(fā)給后端服務(wù)器:
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend.example.com;
}
可觀看 Content Caching,學(xué)習(xí)如何極大提升 web 站點的性能症杏,深入了解 nginx 的緩存功能装获。
優(yōu)化 nginx 的速度
對于提供內(nèi)容服務(wù)來說,加載速度是一個關(guān)鍵的性能指標(biāo)厉颤。通過對 nginx 做一些微小的配置穴豫,可能會極大提升 nginx 的性能,幫助 nginx 優(yōu)化到接近最佳的狀態(tài)逼友。
開啟 sendfile
默認(rèn)情況下精肃,nginx 自己負(fù)責(zé)處理文件的發(fā)送,在發(fā)送文件時帜乞,它將文件拷貝的 tcp 發(fā)送緩沖司抱。
開啟 sendfile 指令,會消除將數(shù)據(jù)復(fù)制到發(fā)送緩沖這一步驟黎烈,它使數(shù)據(jù)可以直接從一個文件描述符復(fù)制到另一個文件描述符习柠。另外,為防止一個快速的連接完全占用 worker 進(jìn)程怨喘,可限制一個 sendfile() 系統(tǒng)調(diào)用可以傳遞的數(shù)據(jù)量大小,使用 sendfile_max_chunk 指令:
location /mp3 {
sendfile on;
sendfile_max_chunk 1m;
...
}
開啟 tcp_nopush
tcp_nopush 指令聯(lián)合 sendfile on 一起使用振定,這時必怜,當(dāng) nginx 通過 sendfile 獲取到數(shù)據(jù)塊之后,nginx 立即發(fā)送 HTTP 響應(yīng)首部后频。
location /mp3 {
sendfile on;
tcp_nopush on;
...
}
開啟 tcp_nodelay
tcp_nodelay 指令允許對 Nagle’s algorithm 進(jìn)行覆蓋梳庆。該算法被設(shè)計用于解決在低速網(wǎng)絡(luò)中發(fā)送小數(shù)據(jù)報文的問題。該算法將一定數(shù)量的小報文整合為一個大數(shù)據(jù)報文卑惜,并以 200ms 的延遲發(fā)送該報文膏执。到了現(xiàn)在的時代,當(dāng)提供很大的靜態(tài)文件時露久,可以無需在意報文的大小更米,可以立即發(fā)送數(shù)據(jù)報文。該延遲也會影響在線應(yīng)用(ssh毫痕,在線游戲征峦,在線交易)迟几。
tcp_nodelay 指令默認(rèn)設(shè)置為 on勿负,意味著停止使用 Nagle’s algorithm 算法舌狗。tcp_nodelay 只用于持久連接中:
location /mp3 {
tcp_nodelay on;
keepalive_timeout 65;
...
}
優(yōu)化 Backlog Queue
nginx 最重要的一個能力是可以快速的處理訪問連接。
一般對于連接的處理是這樣的:當(dāng)一個連接建立之后冒晰,它將被放入監(jiān)聽套接字的 listen 隊列之中蛉加。在普通的訪問壓力下蚜枢,這個隊列很短或者根本沒有這個隊列。但如果在高的訪問壓力下针饥,這個隊列可能會急速地增長厂抽,從而引起性能抖動,連接丟失打厘,或訪問延遲的問題修肠。
測量 Listen Queue
執(zhí)行命令:
netstat -Lan
譯注:這是 BSD 環(huán)境下 netstat,Linux 下的 netstat 輸出有所不同
命令輸出可能如下:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
10/0/128 *.80
0/0/128 *.8080
該輸出顯示:監(jiān)聽端口 80 上有 10 個未接受的連接請求户盯,其隊列上限為 128嵌施,這是一般訪問壓力下的請求。
訪問壓力較大時莽鸭,可能輸出如下:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
192/0/128 *.80
0/0/128 *.8080
顯示有 192 個未接受的連接請求吗伤,超出了 128 的上限值。當(dāng)一個 web 站點訪問壓力大時硫眨,這是很常見的輸出足淆。為了得到優(yōu)化的性能,你需要增加等待隊列的上限值礁阁,為此我們需要調(diào)整操作系統(tǒng)的參數(shù)以及 nginx 的配置參數(shù)巧号。
調(diào)優(yōu)系統(tǒng)參數(shù)
為了應(yīng)對訪問高峰流量,調(diào)整 net.core.somaxconn 鍵值的值(默認(rèn)為 128):
對于 FreeBSD姥闭,執(zhí)行:
sudo sysctl kern.ipc.somaxconn=4096
對于 Linux丹鸿,執(zhí)行:
sudo sysctl -w net.core.somaxconn=4096
打開 /etc/sysctl.conf 文件
vi /etc/sysctl.conf
添加一行內(nèi)容如下:
net.core.somaxconn = 4096
調(diào)優(yōu) nginx
如果你設(shè)置了 somaxconn 值為大于 512 的值,你需要修改 listen 指令的 backlog 參數(shù)與之匹配:
server {
listen 80 backlog 4096;
# The rest of server configuration
}
版權(quán)信息:
*本文編譯自 nginx.com