Nginx之(三)Nginx配置

冰河winner發表於2016-12-24

一個簡單的配置檔案如下:

#定義Nginx執行的使用者及使用者組
user  userName userGroupName;
 
#工作程式數目,根據硬體調整,通常等於CPU數量或者2倍於CPU
worker_processes  1;
 
#錯誤日誌路徑與級別,級別選項:debug|info|notice|warn|error|crit|alert|emerg
error_log  logs/error.log debug;
 
#pid(程式識別符號)存放路徑
pid  logs/nginx.pid;
 
 
events {
 
    #每個工作程式的最大連線數量
    worker_connections  1024;
 
    #連線超時時間,這裡指的是http層面的keep-alive並非tcp的keepalive
    keepalive_timeout  60;
 
    #指定IO模型,linux建議epoll,FreeBSD建議採用kqueue,window下不指定
    use epoll;
 
}
 
#設定http伺服器
http {
 
    #副檔名與檔案型別對映表
    include mime.types;
 
    #預設檔案型別
    default_type  text/html;
 
    #日誌格式設定,main為日誌格式的名稱可在後文中引用
    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 logs/access.log  main;       
   
    #sendfile指令指定 nginx是否呼叫sendfile 函式(zero copy 方式)來輸出檔案,對於普通應用,必須設為on。   
    #如果用來進行下載等應用磁碟IO重負載應用,可設定為off,以平衡磁碟與網路IO處理速度,降低系統uptime。   
    sendfile on;  
 
    #允許或禁止使用socket的TCP_CORK的選項,此選項僅在使用sendfile的時候使用   
    tcp_nopush on;   
   
    #超時時間   
    keepalive_timeout  65;   
 
    #是否開啟gzip壓縮   
    #gzip on;
        
    #虛擬主機配置,下可以有多個location用來表示不同的反向代理       
    server {     
   
             #監聽埠       
             listen  80;      
            
             #主機名,預設為本機       
             server_name  127.0.0.1;   
       
             #編碼      
             charset utf-8;    
 
             #訪問日誌       
             access_log  logs/host.access.log  main;     
 
             #根路徑“/” 的訪問規則        
             location / {     
            
                #網站根目錄           
                root   html;        
                
                #預設網頁           
                index  index.html index.htm index.php;       
             }
     
             #發生404錯誤時跳轉到/404.html頁面       
             error_page  404 /404.html;
 
 
             #配置名為“static_file_server”的主機,按照權重負載均衡
             upstream static_file_server {
                server 192.168.2.1:8080 weight=1;
                server 192.168.2.2:8080 weight=2;
                server 192.168.2.3:8080 weight=3;    
             }
 
             #正規表示式,配置以“.js”、“.css”結尾的路徑的訪問規則
             location ~ .*\.(js|css)?$ {
 
                #將該類請求轉發至static_file_server
                proxy_pass http://static_file_server/
            
                #設定瀏覽器快取過期時間    
                expires  600;
             
                #關閉重定向        
                proxy_redirect  off;          
                
                #以下三行,目的是將代理伺服器收到的使用者的資訊傳到真實伺服器上      
                proxy_set_header  Host $host;    
                proxy_set_header  X-Real-IP $remote_addr;         
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
     
                #拒絕的ip
                deny  127.0.0.1;
     
                #允許的ip
                allow  172.18.5.54; 
     
             }
    }
}

 

3.1 內建變數

在log_format配置項當中,使用了很多Nginx的內建變數,一些變數代表了客戶端請求頭部的一些欄位,如:$http_user_agent,$http_cookie等等,由於這些變數會在請求中定義,所以可能無法保證他們是存在的或者說可以定義到一些別的地方(例如遵循一定的規範)。

常用變數如下:

變數名

說明

$args

請求行中的引數,同$query_string

$content_length

請求頭中的Content-length欄位

$content_type

請求頭中的Content-Type欄位

$document_root

當前請求在root指令中指定的值

$document_uri

不帶請求引數的當前URI,不包含主機名,同$uri

$host

請求中的主機頭欄位,如果請求中的主機頭不可用,則為伺服器處理請求的伺服器名稱

$http_user_agent

客戶瀏覽器資訊

$http_cookie

客戶端cookie資訊

$remote_addr

客戶端的IP地址

$remote_port

客戶端的埠

$remote_user

經過Auth Basic Module驗證的使用者名稱

$request_file_name

當前請求的檔案路徑,由root或alias指令與URI請求生成

$request_method

這個變數是客戶端請求的動作,通常為GET或POST

$request_uri

包含請求引數的原始URI,不包含主機名

$server_addr

伺服器地址

$server_name

伺服器名稱

$server_port

請求到達伺服器的埠號

$server_protocol

請求使用的協議,通常是HTTP/1.0或HTTP/1.1

$scheme

HTTP方法(如http,https)

例:http://localhost:88/test1/test2/test.php

$host:localhost

$server_port:88

$request_uri:http://localhost:88/test1/test2/test.php

$document_uri:/test1/test2/test.php

$document_root:/var/www/html

$request_filename:/var/www/html/test1/test2/test.php


3.2 負載均衡配置

upstream用於配置負載均衡。Nginx的upstream目前支援4種方式的分配:

l   輪詢(預設)

每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。

l   weight

指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況。

例如:

upstream bakend{
    server 192.168.0.14 weight=10;
    server 192.168.0.15 weight=10;
}

l   ip_hash

每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。

例如:

upstream bakend{
    ip_hash;
    server 192.168.0.14:88;
    server 192.168.0.15:80;
}

l   fair(第三方)

按後端伺服器的響應時間來分配請求,響應時間短的優先分配。

upstream backend{
    server server1;
    server server2;
    fair;
}

l   url_hash(第三方)

按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。

例:在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method是使用的hash演算法

upstream backend{
    server squid1:3128;
    server squid2:3128; 
    hash $request_uri;
    hash_method crc32;
}

此外,在負載機器的IP可以附帶狀態引數,例如

upstream bakend{
    ip_hash;
    server 127.0.0.1:9090 down;
    server 127.0.0.1:8080 weight=2;
    server 127.0.0.1:6060;
    server 127.0.0.1:7070 backup;
}

 

每個裝置的狀態設定為:

l   down表示單前的server暫時不參與負載

l   weight為weight越大,負載的權重就越大。

l   backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。


3.3 正則匹配

正則匹配規則:

l   =開頭表示精確匹配

l   ^~ 開頭表示uri以某個常規字串開頭,不是正則匹配

l   ~ 開頭表示區分大小寫的正則匹配

l   ~* 開頭表示不區分大小寫的正則匹配

l   $結尾表示以某字串結尾的正則匹配

看幾個例項:

location  = / {
  #通用匹配, 如果沒有其它匹配,任何請求都會匹配到
  [ configuration A ]
}
 
location  / {
  # 因為所有的地址都以 / 開頭,所以這條規則將匹配到所有請求
  # 但是正則和最長字串會優先匹配
  [ configuration B ]
}
 
location/documents/ {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正規表示式沒有匹配到時,這一條才會採用這一條
  [ configuration C ]
}
 
location ~/documents/Abc {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正規表示式沒有匹配到時,這一條才會採用這一條
  [ configuration CC ]
}
 
location ^~/images/ {
  # 匹配任何以 /images/ 開頭的地址,匹配符合以後,停止往下搜尋正則,採用這一條。
  [ configuration D ]
}
 
location ~*\.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 結尾的請求
  # 然而,所有請求 /images/ 下的圖片會被 config D 處理,因為 ^~ 到達不了這一條正則
  [ configuration E ]
}
 
location/images/ {
  # 字元匹配到 /images/,繼續往下,會發現 ^~ 存在
  [ configuration F ]
}
 
location/images/abc {
  # 最長字元匹配到 /images/abc,繼續往下,會發現 ^~ 存在
  # F與G的放置順序是沒有關係的
  [ configuration G ]
}
 
location ~/images/abc/ {
  # 只有去掉 config D 才有效:先最長匹配 config G 開頭的地址,繼續往下搜尋,匹配到這一條正則,採用
    [ configuration H ]
}

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

上面的匹配結果 按照上面的location寫法,以下的匹配示例成立:

 / -> config A

精確完全匹配,即使/index.html也匹配不了

/downloads/download.html-> config B

匹配B以後,往下沒有任何匹配,採用B

/images/1.gif-> configuration D

匹配到F,往下匹配到D,停止往下

/images/abc/def-> config D

最長匹配到G,往下匹配D,停止往下

你可以看到 任何以/images/開頭的都會匹配到D並停止,FG寫在這裡是沒有任何意義的,H是永遠輪不到的,這裡只是為了說明匹配順序

/documents/document.html-> config C

匹配到C,往下沒有任何匹配,採用C

/documents/1.jpg-> configuration E

匹配到C,往下正則匹配到E

/documents/Abc.jpg-> config CC

最長匹配到C,往下正則順序匹配到CC,不會往下到E

 

所以實際使用中,有三個匹配規則定義可作參考:

#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裡是直接轉發給後端應用伺服器了,也可以是一個靜態首頁
# 第一個必選規則
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二個必選規則是處理靜態檔案請求,這是nginx作為http伺服器的強項
# 有兩種配置模式,目錄匹配或字尾匹配,任選其一或搭配使用
location ^~/static/ {
    root /webroot/static/;
}
location ~*\.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三個規則就是通用規則,用來轉發動態請求到後端應用伺服器
#非靜態檔案請求就預設是動態請求,自己根據實際把握
location / {
    proxy_pass http://tomcat:8080/
}

 

3.4 rewrite配置

rewrite功能就是,使用nginx提供的全域性變數或自己設定的變數,結合正規表示式和標誌位實現url重寫以及重定向。rewrite只能放在server{},location{},if{}中,並且只能對域名後邊的除傳遞引數外的字串起作用,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只對/a/we/index.php重寫。語法:

rewrite regex replacement [flag]

如果想對域名或引數字串起作用,可以使用全域性變數匹配,也可以使用proxy_pass反向代理。

表面看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑做控制訪問或反向代理,可以proxy_pass到其他機器。很多情況下rewrite也會寫在location裡,它們的執行順序是:

(1)執行server塊的rewrite指令

(2)執行location匹配

(3)執行選定的location中的rewrite指令

如果其中某步URI被重寫,則重新迴圈執行1-3,直到找到真實存在的檔案;迴圈超過10次,則返回500 Internal Server Error錯誤。

 

flag標誌位用法如下:

l   last : 相當於Apache的[L]標記,表示完成rewrite

l   break : 停止執行當前虛擬主機的後續rewrite指令集

l   redirect : 返回302臨時重定向,位址列會顯示跳轉後的地址

l   permanent : 返回301永久重定向,位址列會顯示跳轉後的地址

因為301和302不能簡單的只返回狀態碼,還必須有重定向的URL,這就是return指令無法返回301,302的原因了。這裡 last 和 break 區別有點難以理解:last一般寫在server和if中,而break一般使用在location中; last不終止重寫後的url匹配,即新的url會再從server走一遍匹配流程,而break終止重寫後的匹配;break和last都能組織繼續執行後面的rewrite指令。

 

還有一個if指令,非常有用,語法為

if(condition){

...

}

對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行,if條件(conditon)可以是如下任何內容:

l   當表示式只是一個變數時,如果值為空或任何以0開頭的字串都會當做false

l   直接比較變數和內容時,使用=或!=

l   ~正規表示式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配

-f和!-f用來判斷是否存在檔案

-d和!-d用來判斷是否存在目錄

-e和!-e用來判斷是否存在檔案或目錄

-x和!-x用來判斷檔案是否可執行

 

例如:

if($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite請求到/msid/目錄下
 
if ($http_cookie~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正則,設定變數$id等於正則引用部分
 
if($request_method = POST) {
    return 405;
} //如果提交方法為POST,則返回狀態405(Methodnot allowed)。return不能返回301,302
 
if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通過 set 指令設定
 
if (!-f$request_filename){
    break;
    proxy_pass http://127.0.0.1;
} //如果請求的檔名不存在,則反向代理到localhost 。這裡的break也是停止rewrite檢查
 
if ($args ~post=140){
    rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com
 
location ~*\.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.comwww.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盜鏈
}

 

3.5 FastCGI配置

Nginx本身是不支援對外部程式的直接呼叫或者解析,所有的外部程式(包括PHP)必須通過FastCGI介面來呼叫。FastCGI介面在Linux下是socket,(這個socket可以是檔案socket,也可以是ip socket)。為了呼叫CGI程式,還需要一個FastCGI的wrapper(wrapper可以理解為用於啟動另一個程式的程式),這個wrapper繫結在某個固定socket上,如埠或者檔案socket。當Nginx將CGI請求傳送給這個socket的時候,通過FastCGI介面,wrapper接納到請求,然後派生出一個新的執行緒,這個執行緒呼叫直譯器或者外部程式處理指令碼並讀取返回資料;接著,wrapper再將返回的資料通過FastCGI介面,沿著固定的socket傳遞給Nginx;最後,Nginx將返回的資料傳送給客戶端。

以下為Nginx支援PHP的配置示例:

location ~\.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    include        fastcgi_params;
}

通過location指令,將所有以php為字尾的檔案都交給127.0.0.1:9000來處理,而這裡的IP地址和埠就是FastCGI程式監聽的IP地址和埠。 fastcgi_param指令指定放置PHP動態程式的主目錄,也就是$fastcgi_script_name前面指定的路徑,建議將這個目錄與Nginx虛擬主機指定的根目錄保持一致,當然也可以不一致。 fastcgi_params檔案是FastCGI程式的一個引數配置檔案,在安裝Nginx後,會預設生成一個這樣的檔案,這裡通過include指令將FastCGI引數配置檔案包含了進來。 

相關文章