1. 程式人生 > 程式設計 >Nginx 配置常用引數,看這一篇就夠了

Nginx 配置常用引數,看這一篇就夠了

最近在全面學習Nginx,當作筆記了,如有錯誤,歡迎指出或深入交流。

相關文章:

主模組

# 配置使用者或者組,預設為nobody nobody。
#user www www;  

 #Nginx開啟的worker程式數,建議為CPU的核數
#worker_processes 2; 

#指定nginx程式執行檔案存放地址
#pid /nginx/pid/nginx.pid;

#指定日誌路徑,級別。這個設定可以放入全域性塊、http塊、server塊,級別以此為:debug|info|notice|warn|error|crit|alert|emerg
error_log log/error.log debug; #可以在任意地方使用include指令實現配置檔案的包含,類似於apache中的include方法,可減少主配置檔案長度。 include vhosts/*.conf; 複製程式碼

事件模組

events {
    #設定網路連線序列化,防止驚群現象發生,預設為on
    accept_mutex on; 
    
    #預設: 500ms 如果一個程式沒有互斥鎖,它將延遲至少多長時間。預設情況下,延遲是500ms 。
    accept_mutex_delay 100ms; 
    
    #設定一個程式是否同時接受多個網路連線,預設為off
multi_accept on; #事件驅動模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport,不建議設定,nginx會自行選擇 #use epoll; #最大連線數,預設為512 worker_connections 1024; } 複製程式碼

http部分

http {
    #副檔名與檔案型別對映表
    include       mime.types;
    
    # 預設檔案型別,預設為text/plain
    default_type  application/octet-stream; 
    
    #取消服務日誌 
#access_log off; #允許sendfile方式傳輸檔案,預設為off,可以在http塊,server塊,location塊。 sendfile on; #每個程式每次呼叫傳輸數量不能大於設定的值,預設為0,即不設上限。 sendfile_max_chunk 100k; #連線超時時間,預設為75s,可以在http,server,location塊。 keepalive_timeout 65; #開啟gzip資源壓縮 gzip on; # 負載均衡,詳細可看了一篇文章:https://learnku.com/articles/36737 upstream blog { server 192.167.20.19:8081; server 192.168.10.121:8080 weight=5; } #設定請求緩衝 client_header_buffer_size 128k; large_client_header_buffers 4 128k; #上傳檔案的大小限制 預設1m client_max_body_size 8m; server { #單連線請求上限次數。 keepalive_requests 120; #監聽埠 listen 80; #監聽地址 server_name blog.13sai.com; #設定日誌格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /data/logs/access.log main; # 根目錄 root /www/web/public; # 定義錯誤提示頁面 error_page 500 502 503 504 /50x.html; location /static/ { #root與alias主要區別在於nginx如何解釋location後面的uri,這會使兩者分別以不同的方式將請求對映到伺服器檔案上。 #root的處理結果是:root路徑+location路徑 #alias的處理結果是:使用alias路徑替換location路徑 alias /www/static/; #過期30天,靜態檔案不怎麼更新,過期可以設大一點,如果頻繁更新,則可以設定得小一點。 expires 30d; } # 處理php請求到fpm埠 location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://blog; #請求轉向blog 定義的伺服器列表 } #禁止訪問檔案 location ~ /.git { deny all; allow 127.0.0.1; #允許的ip } } } 複製程式碼

部分引數詳細說明

server_name

1.首先選擇所有字串完全匹配的server_name,如 blog.13sai.com 。
2.其次選擇萬用字元在前面的server_name,如 *.13sai.com。
3.再次選擇萬用字元在後面的server_name,如www.13sai.* 。 
4.最後選擇使用正則表示式才匹配的server_name,如 ~^\.sai\.com$

如果都不匹配
1、優先選擇listen配置項後有default或default_server的 
2、找到匹配listen埠的第一個server塊
複製程式碼

location

location
語法: location[=|~|~*|^~|@]/uri/{...}
配置塊: server location會嘗試根據使用者請求中的URI來匹配上面的/uri表示式,如果可以匹配,就選擇 location{}塊中的配置來處理使用者請求。
複製程式碼

location表示式型別

~ 表示執行一個正則匹配,區分大小寫;
~* 表示執行一個正則匹配,不區分大小寫;
^~ 表示普通字元匹配。使用字首匹配。如果匹配成功,則不再匹配其他location; 
= 進行普通字元精確匹配。也就是完全匹配;
@ 它定義一個命名的 location,使用在內部定向時,例如 error_page,try_files
複製程式碼

優先順序:

  • 等號型別(=)的優先順序最高。一旦匹配成功,則不再查詢其他匹配項
  • 字首普通匹配(^~)優先順序次之。不支援正則表示式。使用字首匹配,如果有多個location匹配的話,則使用表示式最長的那個
  • 正則表示式型別(~ ~*)的優先順序次之。一旦匹配成功,則不再查詢其他匹配項
  • 常規字串匹配,如果有多個location匹配的話,則使用表示式最長的那個

(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑)

rewrite


執行順序:
1. 執行server塊的rewrite指令(這裡的塊指的是server關鍵字後{}包圍的區域,其它xx塊類似)
2. 執行location匹配
3. 執行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新迴圈執行1-3,直到找到真實存在的檔案

如果迴圈超過10次,則返回500 Internal Server Error錯誤


語法:rewrite regex replacement [flag]; 預設值:—
上下文:server,location,if
rewrite是實現URL重寫的關鍵指令,根據regex(正則表示式)部分內容,重定向到replacement,結尾是flag標記。 正則:perl相容正則表示式語句進行規則匹配
替代內容:將正則匹配的內容替換成replacement
flag標記:rewrite支援的flag標記
複製程式碼
if指令
語法:if(condition){...}
預設值:無
作用域:server,location
對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行。
if條件(conditon)可以是如下任何內容:

一個變數名;false如果這個變數是空字串或者以0開始的字串;
使用=,!= 比較的一個變數和字串
是用~, ~*與正則表示式匹配的變數,如果這個正則表示式中包含},;則整個表示式需要用" 或' 包圍
使用-f ,!-f 檢查一個檔案是否存在
使用-d,!-d 檢查一個目錄是否存在
使用-e ,!-e 檢查一個檔案、目錄、符號連結是否存在
使用-x , !-x 檢查一個檔案是否可執行
複製程式碼
if例項
if ( $http_user_agent ~ "(MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT-)|(SonyEricsson)|(NEC-)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi-)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG-)|(LG/)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC-)|(SED-)|(EMOL-)|(INNO55)|(ZTE)|(iPhone)|(Android)|(Windows CE)|(Wget)|(Java)|(curl)|(Opera)" ){
    rewrite ^.+ /mobile last; #跳轉到手機站
}


if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}
複製程式碼
last & break
(1)last 和 break 當出現在location 之外時,兩者的作用是一致的沒有任何差異。
注意一點就是,他們會跳過所有的在他們之後的rewrite 模組中的指令,去選擇自己匹配的location
(2)last 和 break 當出現在location 內部時,兩者就存在了差異
-- last: 使用了last 指令,rewrite 後會跳出location 作用域,重新開始再走一次剛剛的行為
-- break: 使用了break 指令,rewrite後不會跳出location 作用域。它的生命也在這個location中終結。

解釋通俗易懂:

last:
        重新將rewrite後的地址在server標籤中執行
break:
        將rewrite後的地址在當前location標籤中執行
複製程式碼
permanent & redirect:
permanent: 永久性重定向。請求日誌中的狀態碼為301
redirect:臨時重定向。請求日誌中的狀態碼為302
複製程式碼

從實現功能的角度上去看,permanent 和 redirect 是一樣的。不存在好壞。也不存在什麼效能上的問題。但是對seo會有影響,這裡要根據需要做出選擇 在 permanent 和 redirect 中提到了 狀態碼 301 和 302。

記住:last 和 break 想對於的訪問日誌的請求狀態碼為200

當你開啟一個網頁,同時開啟debug 模式時,會發現301 和 302 時的行為是這樣的。

第一個請求301 或者 302 後,瀏覽器重新獲取了一個新的URL ,然後會對這個新的URL 重新進行訪問。所以當你配置的是permanent 和 redirect,你對一個URL 的訪問請求,落到伺服器上至少為2次;而當你配置了last 或者是break 時,你最終的URL 確定下來後,不會將這個URL返回給瀏覽器,而是將其扔給了fastcgi_pass或者是proxy_pass指令去處理。請求一個URL ,落到伺服器上的次數就為1次。

注意:配置last 在跨域的時候效果和redirect一致,都是返回302狀態碼,請求地址也發生改變

應用

估算併發

nginx作為http伺服器的時候:

max_clients = worker_processes * worker_connections/2
複製程式碼

nginx作為反向代理伺服器的時候:

max_clients = worker_processes * worker_connections/4  
複製程式碼

限制每個IP的併發連線數

demo:定義一個叫“two”的記錄區,總容量為 10M(超過大小將請求失敗,以變數 $binary_remote_addr 作為會話的判斷基準(即一個地址一個會話)。 限制 /download/ 目錄下,一個會話只能進行一個連線。 簡單點,就是限制 /download/ 目錄下,一個IP只能發起一個連線,多過一個,一律503。

http {
    ...
    limit_conn_zone $binary_remote_addr zone=two:10m;

    server {
        ...
        
        location /download {
            limit_conn   two  1;
        }
    }
}
複製程式碼

限流

demo:定義一個叫“one”的記錄區,佔用空間大小為10m(超過大小將請求失敗),平均處理的請求頻率不能超過每秒一次,也可以設定分鐘速率

http {
    ...
    
    
    limit_req_zone  $binary_remote_addr  zone=one:10m  rate=1r/s;
    

    server {
        ...
        
        location / {
            #快取區佇列burst=5個,nodelay表示不延期(超過的請求失敗),即每秒最多可處理rate+burst個,同時處理rate個。
            limit_req zone=one burst=5 nodelay; 
        }
    }
}
複製程式碼

白名單

http{
    ...
    
    #判斷客戶端的ip地址是否在白名單列表當中,如果返回為0,則在白名單列表當中,否則返回為1
    geo $whiteIpList {
        default  1;
        118.24.109.254 0;
        47.98.147.0/24 1;
        #可以引入一些白名單配置
        include 'whiteIP.conf'
    }
    
    #如果不在白名單之內,返回客戶端的二進位制的ip地址
    map $whiteIpList  $limit {
        default  "";
        1   $binary_remote_addr;
        0   "";
    }
    
    #如果返回的是空字串那麼速率限制會失效
    limit_req_zone $limit zone=test:2m rate=1r/m;
    
    ...
}
複製程式碼

防盜鏈

http {
    ...

    server {
        ...
        
        location ~* \.(gif|jpg|png|swf|flv)$ {
            valid_referers none blocked *.13sai.com;
            if ($invalid_referer) {
                rewrite ^/ blog.13sai.com
            }
        }
    }
}
複製程式碼