Nginx配置靜態資源


靜態服務器

靜態服務器概念非常簡單:當用戶請求靜態資源時,把文件內容回復給用戶。

但是,要把靜態服務做到極致,需要考慮的方面非常多:

  • 正確書寫header:設置content-type、過期時間等
  • 效率:減小文件體積,合理設置緩存,使用策略減少服務器內存占用
  • 安全性,防盜鏈

Nginx提供了強大的靜態服務功能。

基本配置

root和alias:設置靜態資源根目錄

root的取值最好使用絕對路徑。
root 指令可以放在 http、server 或 location 上下文的任何位置。

例如:

server {
    root /www/data;
    location / {
    }
    location /images/ {
    }
    location ~ \.(mp3|mp4) {
        root /www/media;
    }
}

在此配置中,如果 URI 以 mp3 或 mp4 后綴結尾,Nginx 會在 /www/media/ 目錄查找文件。否則在 /www/data 目錄中查找。如果請求以 / 結尾,Nginx 會把這個請求當做一個目錄請求,嘗試找這個目錄中的 index 文件。index 指令定義了 index 文件的文件名(默認使用 index.html 文件)。例如上面的配置,如果請求是 /images/some/path/,Nginx 會嘗試尋找並返回文件 /www/data/images/some/path/index.html,如果文件不存在則返回 404。

autoindex:訪問目錄時列出文件列表

autoindex 指令如果設置為 on,則 Nginx 會返回自動生成的目錄列表。最終的效果和ftp服務相似。

alias和root的區別在於:對於root而言,location匹配的全部路徑就是root下的文件路徑;對於alias而言,location匹配后的路徑才是root下的文件路徑。

index:默認文件

index表示默認的文件。index 指令中可以列出多個文件。Nginx 會按順序查找文件並返回第一個找到的文件。

location / {
    index index.$geo.html index.htm index.html;
}

性能調優

gzip:壓縮文件·

location ~ .*\.(jpg|gif|png)$ {
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;  
    #gzip_http_version 1.0; 
    gzip_comp_level 2;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript 
    application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary off;
    gzip_disable "MSIE [1-6]\.";
    root /nginxtest/images;
}

gzip選項

  • gzip:開啟Gzip
  • gzip_min_length :不壓縮臨界值,大於1K的才壓縮,一般不用改
  • buffer:緩存大小
  • gzip_http_version:用了反向代理的話,末端通信是HTTP/1.0,有需求的應該也不用看我這科普文了;有這句的話注釋了就行了,默認是HTTP/1.1
  • gzip_comp_level :壓縮級別,1-10,數字越大壓縮的越好,時間也越長,看心情隨便改吧
  • gzip_types :第6行:進行壓縮的文件類型,缺啥補啥就行了,JavaScript有兩種寫法,最好都寫上
  • gzip_vary:跟Squid等緩存服務有關,on的話會在Header里增加"Vary: Accept-Encoding"
  • gzip_disable:控制在某些情況下禁用gzip,例如:IE6對Gzip不怎么友好,不給它Gzip了

expires:啟用緩存

location / {
    expires 24h;
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}

sendfile:把小文件加載在內存中

如果靜態文件很小,直接放在內存中可以加快傳輸效率(避免了讀硬盤操作)。如果文件太大也放在內存中,會浪費內存資源。

location /mp3 {
    sendfile           on;
    sendfile_max_chunk 1m;
    ...
}

tcp_nopush

tcp_nopush 指令需要和 sendfile 指令配合使用。
如果 tcp_nopush 指令和 sendfile 指令同時使能,則 Nginx 在通過sendfile 獲取數據塊后會立即在一個數據包中發送 HTTP 響應頭。

tcp_nodelay

tcp_nodelay 選項允許覆蓋 Nagle 的算法,最初設計用於解決慢速網絡中小數據包的問題。該算法將多個小數據包合並為較大的數據包,並以200毫秒的時延發送數據包。如今,在提供大的靜態文件時,無論數據包大小如何,都可以立即發送數據。延遲還會影響在線應用程序(ssh,在線游戲,在線交易)。 默認情況下,tcp_nodelay 指令被使能,禁用 Nagle 的算法。 該選項僅用於保持連接:

location /mp3  {
    tcp_nodelay       on;
    keepalive_timeout 65;
    ...
}

高級調優

測量監聽隊列(Measuring the Listen Queue)

運行下面的命令可以測量監聽隊列(Linux 下的 netstat 命令不支持 -L 參數,需要使用命令 ss -l):

netstat -Lan

1
輸出如下:

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

上面顯示有 10 個未接受的連接,超過了最大限制 128。在網站訪問量大時這種情況挺常見的。為了達到最佳性能,可以修改操作系統和 Nginx 配置,增加 Nginx 可以等待接受的隊列中的最大連接數。

調整操作系統(Linux,FreeBSD)

可以增加 net.core.somaxconn 參數的值(默認 128)以應對高並發流量:

對於 FreeBSD 運行命令 sudo sysctl kern.ipc.somaxconn=4096
對於 Linux 運行命令 sudo sysctl -w net.core.somaxconn=4096
打開文件 /etc/sysctl.conf,添加這一行:net.core.somaxconn = 4096

調整 Nginx

如果設置的 somaxconn 值大於 512,需要更改 Nginx 配置文件中的 backlog 參數匹配這個設置:

server {
    listen 80 backlog=4096;
    # The rest of server configuration
}

安全

使用add_header設置跨域訪問

location / {
    add_header Access-Control-Allow-Origin www.baidu.com;
    add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}

使用referer防盜鏈

location ~ .*\.(jpg|gif|png)$ {
    valid_referers none blocked 119.2x.1x3.218 支持增則匹配;
    if ($invalid_referer) {
            return 403;
    }
    root /nginxtest/images;
}

try_files:定制文件不存在時的操作

try_files 指令可以檢查指定的文件或目錄是否存在,從而執行內部重定向或在文件不存在的時候返回指定的 HTTP 狀態碼。

例如,通過 try_files 指令和 $uri 變量檢查和請求中的 URI 相關的文件是否存在:

server {
    root /www/data;

    location /images/ {
        try_files $uri /images/default.gif;
    }
}

文件以 URI 的形式指定,並且使用在當前 location 或 server 的上下文中設置的 root 或 alias 指令進行處理。此時如果源 URI 指定的文件不存在,Nginx 會內部重定向到最后一個參數指定的 URI,返回 /www/data/images/default.gif。

最后一個參數也可以是狀態碼(前面需要加等號)或一個 location 的名字。下面的例子中,如果 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;
}

參考資料

https://blog.csdn.net/kikajack/article/details/79323643
http://www.nginx.cn/doc/standard/httpcore.html
http://www.nginx.cn/doc/standard/httpgzip.html
http://www.nginx.cn/doc/standard/httpheaders.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM