Nginx配置靜態內容服務器
本節介紹如何使用NGINX來提供靜態內容服務,定義搜索路徑以查找請求的文件的方法,以及如何設置索引文件。
在這個部分,我們主要涉及以下幾個方面的內容:
- 根目錄和索引文件
- 嘗試幾個選項
- 優化NGINX服務內容的速度
1. 根目錄和索引文件
root指令指定將用於搜索文件的根目錄。 要獲取請求文件的路徑,NGINX將請求URI附加到root
指令指定的路徑。 該指令可以放置在http
,server
或location
上下文中的任何級別上。 在下面的示例中,爲虛擬服務器定義了root
指令。 它適用於不包括root
指令的所有location
塊以顯式重新定義根:
server {
root /www/data;
location / {
}
location /images/ {
}
location ~ \.(mp3|mp4) {
root /www/media;
}
}
這裏,NGINX在文件系統的/www/data/images/
目錄中搜索以/images/
開頭的URI。 但是,如果URI以.mp3
或.mp4
擴展名結尾,則NGINX會在/www/media/
目錄中搜索.mp3
或.mp4
文件,因爲它在匹配的location
塊中定義。
如果請求以斜槓結尾,則NGINX將其視爲對目錄的請求,並嘗試在目錄中找到索引文件。index
指令定義索引文件的名稱(默認值爲index.html
)。繼續示例,如果請求URI爲/images/some/path/
,則NGINX會傳遞文件/www/data/images/some/path/index.html
(如果存在)。 如果不存在文件,NGINX默認返回HTTP代碼404
(未找到)。 要配置NGINX以返回自動生成的目錄列表,請將on
參數添加到autoindex
指令中:
location /images/ {
autoindex on;
}
可以在索引指令中列出多個文件名。 NGINX以指定的順序搜索文件,並返回它找到的第一個文件。
location / {
index index.$geo.html index.html index.html;
}
這裏使用的$geo
變量是通過geo指令設置的自定義變量。 變量的值取決於客戶端的IP地址。
要返回索引文件,NGINX檢查其是否存在,然後通過將索引文件的名稱附加到基本URI來對通過URI獲取的內部重定向。內部重定向會導致對某個位置(location
)的新搜索,並且可能會在另一個位置(location
)中結束,如以下示例所示:
location / {
root /data;
index index.html index.php;
}
location ~ \.php {
fastcgi_pass localhost:8000;
...
}
在這裏,如果請求中的URI是/path/
,並且/data/path/index.html
不存在,但是/data/path/index.php
存在,則將/path/index.php
內部重定向映射到第二個位置(location
)。 因此,請求被代理。
2. 嘗試幾個選項
try_files指令可用於檢查指定的文件或目錄是否存在並進行內部重定向,如果沒有指定的文件或目錄,則返回特定的狀態代碼。 例如,要檢查與請求URI相對應的文件的存在,請使用try_files
指令和$uri
變量,如下所示:
server {
root /www/data;
location /images/ {
try_files $uri /images/default.gif;
}
}
該文件以URI的形式指定,它使用在當前位置或虛擬服務器的上下文中設置的 root
或 alias
僞指令進行處理。 在這種情況下,如果與原始URI相對應的文件不存在,則NGINX將內部重定向到最後一個參數中指定的URI,也就是返回/www/data/images/default.gif
。
最後一個參數也可以是一個狀態代碼(直接在前面的等號)或位置的名稱。 在以下示例中,如果try_files
指令的任何參數都不會解析爲現有文件或目錄,則會返回404錯誤。
location / {
try_files $uri $uri/ $uri.html =404;
}
在下一個示例中,如果原始URI和帶有附加尾部斜線的URI都不能解析爲現有文件或目錄,則將請求重定向到將其傳遞給代理服務器的命名位置(location
)。
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend.example.com;
}
3. 優化NGINX服務內容的速度
加載速度是服務任何內容的關鍵因素。 對您的NGINX配置進行小幅優化可能會提高生產力並幫助實現最佳性能。
啓用sendfile
默認情況下,NGINX會自動處理文件傳輸,並在發送文件之前將其複製到緩衝區中。 啓用sendfile指令將消除將數據複製到緩衝區中的步驟,並允許將數據從一個文件描述符直接複製到另一個文件描述符。 或者,爲了防止一個快速連接完全佔用工作進程,您可以通過定義sendfile_max_chunk指令來限制在單個sendfile()
調用中傳輸的數據量:
location /mp3 {
sendfile on;
sendfile_max_chunk 1m;
...
}
啓用tcp_nopush
將tcp_nopush選項與sendfile
一起使用。 該選項將使NGINX能夠通過sendfile
獲取數據塊之後,在一個數據包中發送HTTP響應頭
location /mp3 {
sendfile on;
tcp_nopush on;
...
}
啓用tcp_nodelay
tcp_nodelay選項可以覆蓋Nagle的算法,最初是爲了解決慢網絡中的小數據包問題而設計的。 該算法將大量小數據包整合到較大的數據包中,並以200 ms
的延遲發送數據包。
如今,當服務大型靜態文件時,無論數據包大小如何,都可以立即發送數據。 延遲也會影響在線應用程序(ssh,在線遊戲,網上交易)。 默認情況下,tcp_nodelay
指令設置爲on
,表示Nagle的算法被禁用。 該選項僅用於Keepalive
連接:
location /mp3 {
tcp_nodelay on;
keepalive_timeout 65;
...
}
優化積壓隊列
其中一個重要因素是NGINX可以處理傳入連接的速度。 一般規則是建立連接時,將其放入監聽套接字的「偵聽」隊列中。 在正常負載下,有一個低隊列,或根本沒有隊列。 但是在高負載下,隊列可能會急劇增長,這可能會導致性能不均衡,連接丟失和延遲。
測量偵聽隊列
讓我們來查看當前的偵聽隊列。 運行命令:
netstat -Lan
命令輸出可能如下所示:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
10/0/128 *.80
0/0/128 *.8080
命令輸出顯示端口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
命令輸出顯示超過128個連接限制的192個不可接受的連接。 當網站的流量很大時,這是很常見的。 爲了達到最佳性能,您需要增加NGINX在操作系統和NGINX配置中排隊等待接收的最大連接數。
調整操作系統
將net.core.somaxconn
鍵的值從其默認值(128
)增加到足夠高的值以能夠處理高突發流量:
對於FreeBSD,運行命令:
sudo sysctl kern.ipc.somaxconn=4096
對於FreeBSD,運行命令:
sudo sysctl -w net.core.somaxconn=4096
打開文件:/etc/sysctl.conf
,將下面一行添加到文件並保存文件:
net.core.somaxconn = 4096
調整NGINX
如果將somaxconn
鍵設置爲大於512
的值,請更改NGINX listen指令的backlog
參數以匹配:
server {
listen 80 backlog 4096;
# The rest of server configuration
}