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

已下線發表於2019-11-18

最近在全面學習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匹配的話,則使用表示式最長的那個

return

語法:return code [text] return code URL;
return URL;
配置塊:server,location,if
該指令用於結束規則的執行並返回狀態嗎給客戶端。
狀態碼包括:
204(No Content)、
400(Bad Request)、
402(Payment Required)、
403(Forbidden) 
404(Not Found)、
405(Method Not Allowed)、
406(Not Acceptable)、 
408(Request Timeout)、
410(Gone)、
411(Length Required)、
413(Request Entity Too Large)、
416(Requested Range Not Satisfiable)、 500(Internal Server Error)、
501(Not Implemented)、
502(Bad Gateway)、 
503(Service Unavailable)
504(Gateway Timeout)。

例如,示例,如果訪問的URL以.sh .bash 結尾,返回狀態碼403 
location ~ .*\.(sh|bash)?$ {
    return 403;
}

rewrite

語法:rewrite regex replacement [flag]; 
預設值:—
配置塊:server, location, if
rewrite是實現URL重寫的關鍵指令,根據regex(正規表示式)部分內容,重定向到replacement,結尾是flag標記。 正則:perl相容正規表示式語句進行規則匹配
替代內容:將正則匹配的內容替換成replacement
flag標記:rewrite支援的flag標記

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

如果迴圈超過10次,則返回500 Internal Server Error錯誤
if指令
語法:if(condition){...}
預設值:無
配置塊:server,location
對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行。
if條件(conditon)可以是如下任何內容:

一個變數名;false如果這個變數是空字串或者以0開始的字串;
使用= ,!= 比較的一個變數和字串
是用~, ~*與正規表示式匹配的變數,如果這個正規表示式中包含},;則整個表示式需要用" 或' 包圍
使用-f ,!-f 檢查一個檔案是否存在
使用-d, !-d 檢查一個目錄是否存在
使用-e ,!-e 檢查一個檔案、目錄、符號連結是否存在
使用-x , !-x 檢查一個檔案是否可執行
if例項
if ($http_user_agent~*(mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {
    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 {
        ...
        #valid_referers後面的referer列表進行匹配,如果匹配到了就invalid_referer欄位值為0 否則設定該值為1
        location ~* \.(gif|jpg|png|swf|flv)$ {
            valid_referers none blocked *.13sai.com;
            if ($invalid_referer) {
                rewrite ^/ blog.13sai.com
            }
        }
    }
}

技術文章也釋出在自己的公眾號【愛好歷史的程式設計師】,歡迎掃碼關注,謝謝!

愛好歷史的程式設計師

本作品採用《CC 協議》,轉載必須註明作者和本文連結
分享開發知識,歡迎交流。公眾號:開源到

相關文章