天天看點

 

一:Nginx 後端伺服器組的配置:

1、upstream:

用于設定後端伺服器組的主要指令,upstream類似于之前的server塊或http塊,用法如下:

 

upstreame  Myserver{ 
   #ip_hash;
  #least_conn;
  #fair;
  
  #hash $request_uri;
  #hash_method crc32;
  server 192.168.0.2:8080 #weight 2 max_fails 3 fail_timeout 60;
  192.168.0.3:8080 backup;
  192.168.0.4:8080 down; 
    }    
 #Myserver是後端伺服器組的名稱,在大括号裡面填寫後端伺服器的IP和端口資訊,預設情況下伺服器組被調用以後會使用輪詢排程的方式調用組内的後端伺服器。
 #keepalived_timeout; #保持的空閑會話的時常,在此時間内用戶端不進行操作,伺服器将斷開與用戶端的連接配接。此數值不能太大,Nginx從1.1.4開始支援。
 #ip_hash; 實作會話保持功能,即将某個用戶端的請求定向到組内的同一台伺服器,保證用戶端與伺服器之間建立穩定的會話,隻有伺服器處于無效狀态時,會話才會被轉發給組内其他的伺服器。
 #server 用于定義一台後端伺服器。
 #192.168.0.2:8080 是後端伺服器的IP,端口是8080。
 #weight = number; #配置權重,與ip_hash有沖突,因為ip_hash是将請求固定在同一個後端伺服器的,而weight是根據權重輪訓的,是以不能同時配置在一個upstream内。
 #max_fails = number #設定一個失敗的請求次數,在一定時間内超過這個次數就認為伺服器是無效的,如可以設定為3。
 #在失敗3次以後的60秒将不再将請求分發給失效的server也不在檢查此server的狀态,預設時間是10秒。
 #backup; #将一台伺服器标記為備份伺服器,隻有當所有正常伺服器全部不可用的時候才會使用備份的伺服器。
 #down  #将一台伺服器标記為永久不可用的狀态,通常與ip_hash配合使用。      
 

 2、nginx 的 upstream支援的集中排程算法:

 
1、輪詢(預設) 
   每個請求按時間順序逐一配置設定到不同的後端伺服器,如果後端伺服器down掉,能自動删除。 
2、weight 
   指定輪詢幾率,weight和通路比率成正比,用于後端伺服器性能不均的情況。 
3、ip_hash 
   每個請求按通路ip的hash結果配置設定,這樣每個訪客固定通路一個後端伺服器,可以解決session 保持的問題。  
4、fair(第三方) 
   可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定,Nginx本身預設是不支援fair的,如果需要使用這種排程算法,必須下載下傳Nginx的upstream_fair子產品。
5、url_hash(第三方)
  按通路url的hash結果來配置設定請求,使每個url定向到同一個後端伺服器,可以進一步提高後端緩存伺服器的效率,Nginx本身預設是不支援url_hash的,如果需要這種高度算法,必須安裝Nginx的hash軟體包。
6、least_conn 
  根據後端伺服器的連接配接狀況進行配置設定客戶請求,連接配接最少的伺服器将被有限配置設定用戶端請求。      
 

二:Nginx伺服器的rewrite功能介紹:

 Nginx伺服器利用ngx_http_rewrite_module 子產品解析和處理rewrite請求,是以說此功能依靠 PCRE(perl compatible regularexpression),是以編譯之前要安裝PCRE庫,rewrite功能時nginx伺服器的基本功能之一,用于實作URL的重寫,URL的重寫是非常有用的功能,比如它可以在我們改變網站結構之後,不需要用戶端修改原來的書簽,也無需其他網站修改我們的連結,就可以設定為通路,另外還可以在一定程度上提高網站的安全性。

1、位址重寫與位址轉發:

位址重寫和位址轉發是兩個不同的概念,位址重寫是實際上是為了實作址标準化,就像通路www.baidu.cn可以出現www.baidu.com的首頁,伺服器會把www.baidu.cn重寫成www.baidu.com,浏覽器的位址欄也會顯示www.baidu.com,而轉發指的是将一個域名指向另一個已有站點的過程,位址欄的位址保持不變,是以位址轉發和位址重寫的大緻差別如下:

 
位址轉發後用戶端浏覽器位址欄中的位址顯示是不變的,而位址重寫後位址欄中的位址會變成正确的位址。
在一次位址轉發過程中隻會産生一次網絡請求,而一次位址重寫産生兩次請求。
位址轉發一般發生在同一站點項目内,而位址重寫則沒有限制。
位址轉發到的頁面可以不用全路徑名表示,而位址重寫到的頁面必須使用完全的路徑名表示。
位址轉發過程中,可以将用戶端請求的request範圍内的屬性傳遞給新的頁面,但位址重寫不可以。
位址轉發的速度比位址重寫的速度快。      
 

  2、if指令:

2.1:用于條件判斷,并根據條件判斷結果選擇不同的Nginx配置,可以配置在server或location塊中進行配置,用法如下:

if ($變量) { 
  action
}      

注: 如果$變量的值為空字元串或是以0開頭的任意字元串,則if指令認為該條件為false,其他條件為true。

2.2:使用“=”(等于)和“!=”(不等于)比較變量和字元串是否相等,相等時if指令認為該條件為true,反之為false。

if ($request_method = POST) {
      return 405;  
} #條件裡的字元串不需要加引号      

2.3:使用正規表達式對變量進行比對,比對成功時if指令認為條件為true,否則認為false,變量與表達式之間使用以下符号連結:

雙目測試:運算所需變量為兩個的運算符叫做雙目運算符,如下幾個運算符:

~: #表示在比對過程中區分大小寫字元,(可以通過正規表達式比對),滿足比對條件為真,不滿足為假。
~*: #表示在比對過程中不區分大小寫字元,(可以通過正規表達式比對),滿足比對條件為真,不滿足問假。
!~:#區分大小寫不比對,不滿足為真,滿足為假,不滿足為真。
!~*:#為不區分大小寫不比對,滿足為假,不滿足為真。      

^~ :#如果把這個字首用于一個正常字元串,那麼告訴nginx 如果路徑比對那麼不測試正規表達式。

注意:使用~和~!在比對成功時if指令認為條件為true,比對失敗為false,使用!~和!~*比對失敗時if指令認為條件為true,否則為false,在正規表達式中,可以使用小括号對變量進行截取,在大括号中使用$!...$9引用截取的值,如下:

 
if ($http_user_agent ~ MSIE) {  #if語句盡量用在location當中,盡量不要在http或server中使用,會出現莫名的錯誤。
     #判斷用戶端的浏覽器中是否含有MSIE的字元串,如果包含則為true  
}

#########################################
if ($http_cookie ~* "id="([^;]+)(?:;)") {
    #Nginx配置,可以使用$!和$2擷取截取到的值,如:
     # set $id $1; 将截取到的id的值指派給$id變量以備後用  
}
注意:整個正規表達式一般不需要加引号,但是如果含有右大括号"}"或者分分号";"的時候,就必須要給整個正規表達式加上引号""      
 

3、檔案和目錄測試:單目測試,判斷檔案或者目錄是否存在

3.1 -f和! -f:判斷請求的檔案是否存在和是否不存在

 
-f 表示如果請求的檔案存在,則if指令為true,如果請求的檔案不存在,則if指令為false。使用! -f的時候,如果請求的檔案不存在但是目錄存在,if指令認為條件為true,如果請求的檔案和目錄都不存在,則if指令認為條件為false,如果請求的檔案存在,也為false,如下:
if (-f $request_filename) {
    #判斷請求的檔案是否存在
}

if (! -f $request_filename) {
   #判斷請求的檔案是否不存在
}      
 

3.2 -d和! -d: #判斷請求的目錄是否存在和是否不存在。

使用-d時,如果請求的目錄存在,則if指令認為條件為true,如果請求的目錄不存在,則認為條件為false,當使用! -d的時候,如果請求的目錄不存在但是目錄的上級存在,if指令認為條件為true,如果該目錄和他的上級都不存在,則為false,如果請求的目錄存在也未false,和of和! -f基本一緻。      

3.3 -e和! -e: #判斷請求的檔案或目錄是否存在和是否不存在。

判斷檔案或目錄是否存在,相當于-f和-d的功能合體,當使用-e時,如果請求的檔案或目錄存在則if指令認為條件為true,否則為false,當使用! -e時,如果請求的檔案或目錄以及該檔案的上級都不存在,則為false,否則為true。      

3.4 -x和 ! -x: #判斷檔案是否可執行和是否不可執行。

使用-x如果檔案可執行則傳回true,否則為fasle,使用! -x的時候如果檔案不可執行傳回true,否則為false。      

4、break指令:用于中斷目前相同作用域中的其他Nginx配置,與該指令處于同一作用域的Nginx配置中,位于它前面的配置生效,位于後面的指令配置就不再生效了,Nginx伺服器在根據配置處理請求的過程中遇到該指令的時候,回到上一層作用域繼續向下讀取配置,該指令可以在server塊和location塊以及if塊中使用,使用文法如下:

location /test {
        root   html;
        index  index.html index.htm;  
     break;  #return之後的将不再執行,之前的可以執行
      }      

 5、return指令:用于完成對請求的處理,并直接向用戶端傳回響應狀态碼,處于此指令後的所有配置都将不被執行,return可以在server、if和location塊進行配置,用法如下:

return (text); #傳回給用戶端的響應體内容,可以調用變量
return code; #傳回給用戶端HTTP狀态碼,範圍為0-999
return URL; #傳回給用戶端的URL位址      

注意:從nginx 0.8.42開始,當code使用301時表示永久重定向,302為臨時重定向。303表示目前的響應可以在另一個URL找到,307表示請求的資源臨時從不同的URL響應

6、rewrite指令:通過正規表達式的比對來改變URI,可以同時存在一個或多個指令,按照順序依次對URI進行比對。

 
URI(universal resource identifier):通用資源辨別符,用于對網絡中各種資源進行标示,有存放資源的主機名、片段辨別符和相對URL三部分組成,存放資源的主機名一把由傳輸協定(scheme)、主機和資源路徑三部分組成,片段辨別符執行資源内容的具體元素,相對URL标示主機上的相對路徑,一般格式為:scheme:[//] [[使用者名[:密碼]@]主機名:[端口号]][/資源路徑名],如http://www.a.com:8080/path/file/index.html,Nginx就是對其中的URI /path/file這部分進行處理和比對,但是不能處理http://www.a.com,因為Nginx接受到的URL不包含http://www.a.com。
URL(uniform resource location):統一資源定位符,是用于在Internet中描述資源的字元串,是URL的子集,主要包括傳世協定(scheme)、主機(IP、端口号或者域名)和資源具體位址(目錄和檔案名)等三部分,一般格式為 scheme://主機名[:端口号][/資源路徑],如:http://www.a.com:8080/path/file/index.html就是一個URL路徑
URI就是一種資源定位機制,它是比較籠統地定位了資源,并不局限于用戶端和伺服器,而URL就定位了網上的一切資源,隻要是網上的資源,都有唯一的URL。      
 

注:rewrite指令接收到的URI為 /path/file,不包含參數,如/path/file/arg1=value1&argv2=value2,隻會接收到/path/file,不包含arg1=value1&argv2=value2,但是我們可以使用nginx内置的全局變量$request_uri來比對使用者的uri,在$request_uri後面要添加問号,replacement支援nginx全局變量的使用,常用的還要$uri和$args等,如:

rewrite www.a.com  http://www.b.com$request_uri? permanent;      

注意:replacement是比對成功後用于替換URL中被截取内容的字元串,預設情況下,如果該字元串是有http://或者https://開頭的,則不會繼續向下進行其他處理,而且直接将重寫後的URL傳回給用戶端。

7、flag:用來設定rewrite對URI處理的行為或動作,可以為一下四個當中的一個:

7.1、last:終止繼續在本location塊中處理接受到的URL,并将在本location中重新的URL作為一個新的URL,繼續使用後面的各location塊進行處理,該标志将重寫後的URL重新再server塊中執行,為重寫後的URI轉入到其他location塊并繼續處理的機制,nginx伺服器的last處理超過10次循環之後将傳回錯誤代碼500,使用方法如下:

location / {
    rewrite ^(/test/.*)/msie(.*)\..*$  $1/test/mp3/$2.html break;
    rewrite ^(/test/.*)/other(.*)\.*$ $1/test/other/$2.html break;    
}      

注:如果URI在第二行被比對成功并處理,Nginx伺服器不會繼續使用第三行的配置和比對處理新的URL,而是讓所有的location快重新比對和處理新的URI,即一旦在本location中比對成功一行,就跳出本location并在下一個location比對,直到在下一個location比對成功後再跳出下一個location繼續下下一個,直到最後一個為止。

7.3、break:将你的URI作為一個新的URI,在本快中繼續進行處理,該标志将重寫後的位址在目前的location快中執行,不會将新的URI轉向其他的location子產品,如下:

 
注意:如果第二行被比對并處理成功,Nginx伺服器将新的URI繼續在本location塊中使用第三行比對和處理,新的URI始終在一個location之内比對和處理,直到本location最後一個比對條件。last一般寫在server和if中,而break一般使用在location中
1、last一般寫在server和if中,而break一般使用在location中
2、last不終止重寫後的url比對,即新的url會再從server走一遍比對流程,而break終止重寫後的比對
3、break和last都會繼續執行後面的rewrite指令,隻是last會終止本location的比對跳轉到其他location,而break隻會在目前location繼續比對,直到最後一條比對結果為止,不會跳轉到其他location。      
 

7.4、redirect:将重寫後的URI傳回給用戶端,狀态碼為302,指明是臨時重定向URI,主要用在replacement變量不是以http或https開頭的情況下。

7.5、permanent:将重寫後的URI傳回給用戶端,代碼為301,注明是永久重定向。

注意:在使用flag的時候,

8、rewrite_log:用于配置是否開啟URL重寫日志的輸出功能,用法如下:

rewrite_log on|off; #預設為off。,如果設定為開啟,URL的相關日志将以notice級别的輸出到error_log配置的檔案當中。      

9、set:用于設定一個新的變量,其用法結構為:

set  variable value;  #variable為變量的名稱,要使用$作為變量的第一個字元,且變量名不能與nginx伺服器預設的全局變量相同
value:為變量的值,可以是字元串、其他變量和變量組合等。      

10、uninitialized_variable_warn:用于配置使用未初始化的變量時,是否記錄告警日志,用法如下:

uninitialized_variable_warn on|off;      

 4、root和alias:

root:指定web的家目錄,在定義location的時候,檔案的絕對路徑等于 root+location,如:

location /bbs {
        root   html;  #必須要在html目錄中建立一個bbs目錄才可以通路,否則報錯。
        index  index.html;
        }      

alias:定義路徑别名,會把通路的路徑重新定義到其指定的路徑,如:

location /newweb { #當通路newweb的時候,會顯示alias定義的 /usr/local/nginx/html/newweb/裡面的内容。
        alias  /usr/local/nginx/html/newweb/;
        }      

注:alias後面必須要用“/”結束,否則會找不到檔案,而root要結合location,要麼都有/,要麼都沒有/,如果一個有一個沒有在通路的時候會出錯。

三、Rewrite常用的全局變量:

1.Nginx伺服器内置了很多預先定義好的内置變量,就要友善擷取很多相關的伺服器資訊以及與請求相關的指令、參數當資訊,可以更加友善的使用者進行自定義的功能定義等,具體變量如下如下:

1.1、$args:變量中存放了URL中的指令,比如http://mobile.weathercn.com/index.do?id=101290101&partner=中的id=101290101&partner=,而且可以有多個指令。

1.2、$content_length:儲存了請求封包頭部中的content-lenght字段。

1.3、$content_type:儲存了請求頭部中的content-type字段。

1.4、$document_root:儲存了針對目前資源的請求的系統根目錄。如:

 

1.5、$document_uri:儲存了目前請求中不包含指令的URI,主注意是不包含請求的指令,比如http://hfnginx.chinacloudapp.cn/index.do?id=101060101&partner=會被定義為/index.do。

1.6、$host:存放了請求的伺服器名稱。

1.7、$http_user_agent:用戶端浏覽器的詳細資訊,如使用chrome和Firefox通路則顯示如下:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 #chrome的浏覽器資訊
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0  #Firefox的浏覽器資訊      

1.8、$http_cookie:用戶端的cookie資訊。

1.9、$limit_rate:如果nginx伺服器使用limit_rate配置了顯示網絡速率,則會顯示,如果沒有設定, 則顯示0。

1.2.0:$remote_addr:存放了用戶端的位址,注意是用戶端的公網IP,也就是一家人通路一個網站,則會顯示為路由器的公網IP,如下:

 

1.2.1:$remote_port:用戶端請求Nginx伺服器時随機打開的端口,這是每個用戶端自己的端口。

1.2.2:$remote_user:已經經過Auth Basic Module驗證的使用者名。

1.2.3:$request_body_file:做反向代理時發給後端伺服器的本地資源的名稱。

1.2.4:$request_method:請求資源的方式,GET/PUT/DELETE等

1.2.5:$request_filename:目前請求的資源檔案的路徑名稱,由root或alias指令與URI請求生成。

/usr/local/nginx//html/web/      

1.2.6:$request_uri:包含請求參數的原始URI,不包含主機名,如:”/index.do?id=101020100&partner=”。

/web/      

1.2.7:$squery_string:儲存了URL請求的指令,與 $args相同。

1.2.8:$scheme:請求的協定,如ftp,https,http等。

1.2.9:$server_protocpl:儲存了用戶端請求資源使用的協定的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等。

1.3.0:$server_addr:儲存了伺服器的IP位址。

192.168.0.24      

1.3.1:$server_name:伺服器的主機名。

hfnginx.chinacloudapp.cn      

1.3.2:$server_port:伺服器的端口号。

80      

1.3.3:$uri:與$document_uri相同,是一個不包含指令的uri位址。

如通路:hfnginx.chinacloudapp.cn/index.do?id=101020100&partner=,uri如下:
/index.do      

四:rewrite 功能的具體使用: 

nginx rewrite功能使用子產品ngx_http_rewrite_module,rewrite是nginx伺服器的重要子產品之一,它一方面實作了URL的重寫功能,另一方面為Nginx伺服器提供反向代理伺服器的支援,使用如下:

1、proxy_pass:反向代理,将使用者的請求代理至後端伺服器:

 
server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location /form/ {  #比對一個通路的目錄
            proxy_pass  http://192.168.0.201/bbs/;  #/form後面的斜杠要和http://192.168.0.201/bbs後面的斜杠要麼都有要麼都沒有,否則通路比對會出現錯誤。      
} }      
 

1.1通路結果:

 

 1.2通路過程第一次是一個301(頁面永久重定向)如下:

 

1.3通路過程第二次,傳回頁面的内容:

 

2.使用正則比對通路頁面:

 
server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location ~* ^/form {
            proxy_pass  http://192.168.0.201;  #使用正則的話,http://192.168.0.201後面不支援加目錄,否則文法錯誤,後端伺服器Web的目錄要和location設定的/form同名,否則報404頁面找不到錯誤。 
} }      
 

2.1:後端伺服器的web目錄:

[root@Server1 html]# ls
bbs
[root@Server1 html]# mv bbs form #将上一個例子中的bbs目錄重命名成form,form對應locati的名稱
[root@Server1 html]# ls
form      

2.2:通路測試,步驟也是兩次,一次301,一次正常頁面:

 

 2.3:配置Nginx轉發用戶端IP:

location ~* ^/form {
            proxy_pass  http://192.168.0.201;
            proxy_set_header X-Real-IP $remote_addr;
        }      

2.4:http預設無法記錄這個變量,是以要手動設定apache的日志格式:

[root@Server1 httpd]# vim /etc/httpd/conf/httpd.conf 
更改配置檔案中日志格式的一行:
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined  #%{X-Real-IP}i表示是頭部封包中某個變量的值,i是取值,取得是封包中X-Real-IP對應的值。這個值就是用戶端的真實IP      

2.5:重新通路并檢視apache日志:

[root@Server1 httpd]# tail -n 1 /var/log/httpd/access_log 
47.88.87.169 - - [07/May/2016:19:39:43 +0800] "GET /form/ HTTP/1.0" 200 38 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"      

五:臨時重定向與永久重定向:

1.防盜鍊:

referer是記錄打開一個頁面之前記錄是從哪個頁面跳轉過來的,如果别人隻連結了自己網站圖檔或某個單獨的資源,而不是網站的頁面,這就是盜鍊,

location /image {
            valid_referers none blocked www.baidu.com;
    if ($invalid_referer) {
          return 403;
} #none是使用者正常在浏覽器輸入位址通路的請求連接配接 #blocked 類似于防火牆法則,隻要不符合給定條件的就認定是不合法的,就拒絕通路。      

2.通過rewrite完成位址重寫:

301:永久重定向,一般資源都在伺服器内部,用戶端請求一次即可完成資料的傳回。

302:臨時重定向,當nginx作為代理伺服器,并使用rewrite重寫使用者請求的URL的到其他伺服器的時候,就是臨時重定向。

 
server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            root   html;  #定義存放web的目錄
            index  index.html;
            #rewrite ^/bbs/(.*)$  http://www.weather.com.cn/$1;  #将請求轉發給其他伺服器處理,是臨時重定向,用戶端需要在伺服器傳回封包中頭部中查找到location字段并根據其中的路徑到新伺服器發送請求。
            rewrite ^/bbs/(.*)$   /web/$1;  #/web是在html目錄下,也就是這裡的跟就是html目錄,将請求在伺服器記憶體處理并傳回給使用者,是永久重定向的方式
        } 
}      
 

2.1臨時重定向請求過程如下:

 

2.2:永久重定向如下:

 

六:rewrite後面的四個flag:

1.last:本次重寫完成之後,重新開機下一輪檢查,大多數情況下使用last,但是如果比對寫的有問題,會導緻出現循環比對,直到十次之後出錯。

2.break:本次完成重寫之後,直接執行後續資料操作,不再進行其他的條件比對,在非跟location使用rewrite比對的時候要使用break,避免導緻循環。

3.redirect:傳回302臨時重定向,如果替換字段用http://開頭則被使用。

4.permanent:傳回301永久重定向。

七:對Apache實作上傳下載下傳分離:

 1.确認子產品當中有dav子產品:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_lock_module modules/mod_dav_lock.so      

2、打開dav功能:

<Directory "/var/www/html">
Dav on #加一行      

3、重新開機httpd:

[root@Server1 html]# systemctl  restart  httpd      

4、将www目錄改為apache權限,并使用curl -T指令測試上傳:

 
[root@Server1 html]# chown  apache:apache /var/www/html/ -R  #更改屬主屬組
[root@Server1 html]# curl -T  /etc/issue http://192.168.0.202  #上傳一個檔案
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201 Created</title>
</head><body>
<h1>Created</h1>
<p>Resource /issue has been created.</p>  #傳回上傳成功
</body></html>

驗證:      

 [root@Server1 html]# ls /var/www/html/

    form index.html issue

 

5、用戶端使用浏覽器通路測試:

 

6、通過Nginx實作下載下傳和上傳的分離:

 
server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            #root   html;
            index  index.html;
            proxy_pass  http://192.168.0.201;
            if ($request_method = "PUT"){  #假如請求的方法是上傳
                proxy_pass  http://192.168.0.202;
                }
        }
}
      
 

7、測試上傳是否生效:

 

8、伺服器驗證上傳的檔案:

 

 八:幾個代表性的例子:

1.location比對定義的目錄:

 
location = / {  #精确比對,/後面不能加任何字元串,符合此條件就直接傳回資料,不再像下比對。
    if (-d $request_filename) {
         root /usr/local/nginx/html/;  #當使用者通路newweb的時候,則顯示此目錄的内容,除此之外通路其他的任何目錄都不比對。
  [動作A]
}

location  / {
  # 因為所有的位址都以/開頭,是以這條規則将比對到所有請求,但是非精确比對會采取正則和最長字元串會優先比對,是以還會向下繼續比對,比如當通路/bbs的時候,還需要看下面是否更精确的比對。
  [ 動作B] 
}

location /documents/ {
  # 比對任何以 /documents/ 開頭的位址,比對符合以後,還要繼續往下搜尋
  # 如果後面的正規表達式都沒有比對到,就比對這一條
  [動作C] 
}

location ^~ /images/ {   #比對任何以/images/ 開頭的任何請求并且停止搜尋,後面任何正規表達式将不會被測試。
  # 比對任何以 /images/ 開頭的位址,比對符合以後,停止往下搜尋正則,采用這一條。
  [動作D] 
}

location ~* \.(gif|jpg|jpeg)$ {  #~*為不區分大小寫
  # 比對所有以 gif,jpg或jpeg 結尾的請求
  # 然而,所有請求/images/下的圖檔會被動作D比對處理,因為動作D有^~會優先比對并終止比對,是以到達不了這一條正則
  [動作E] 
}

location /images/ {
  # 字元比對到 /images/,繼續往下,會發現 ^~ 存在,如果動作D存在,則這一條就不生效。
  [動作F] 
}

location /images/abc {
  #最長字元比對到 /images/abc,繼續往下,會發現 ^~ 存在,如果D存在,則這一條就不生效。
  #F與G的放置順序是沒有關系的
  [動作G] 
}

location ~ /images/abc/ {
  # 動作D存在,這一條不生效,如果登出動作D,則會優先最長比對 動作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      
 

2.if判斷語句:

 
if ($http_user_agent ~ MSIE) { #如果用戶端是微軟的IE浏覽器,就将請求rewrite到msie目錄下。
    rewrite ^(.*)$ /msie/$1 break;
} 

if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # 如果cookie比對正則,就設定變量$id等于正則引用部分
    set $id $1; 設定$id等于正則第一個括号内比對的部分
 } 

if ($request_method = POST) { #如果送出方法為POST,則傳回狀态405(Method not allowed)。return不能傳回301,302
    return 405;
} 

if ($slow) { #限速,$slow可以通過 set 指令設定
    limit_rate 10k;
} 

if (!-f $request_filename){ #如果請求的檔案名不存在,則反向代理到localhost 。這裡的break也是停止rewrite檢查
    break;
    proxy_pass  http://127.0.0.1; 
} 

if ($args ~ post=140){ #如果query string中包含"post=140",永久重定向到example.com
    rewrite ^ http://example.com/ permanent;
}       
 

3、關于防盜鍊:

 
location ~* \.(gif|jpg|png|swf|flv)$ { # 防盜鍊設定,對于字尾是gif、jgp等格式的生效
    valid_referers none blocked  a.com  *.a.com; #定義允許通路的請求連結
    if ($invalid_referer) {
        return 404;
    }
}

none:在浏覽器輸入網站域名直接通路的請求,需要允許通路的
blocked:有referer首部,但是referer首部被清除了,一般是防火牆改過的請求
server_name:帶伺服器名稱的,一般是本機或其他伺服器的請求,a.com和*.a.com是本公司的域名,要允許通路于是要先允許本機的通路,再禁止其他伺服器的通路      
 

4.實際使用建議:

 
實際使用中,個人覺得至少有三個比對規則定義,如下:
#直接比對網站根,通過域名通路網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裡是直接轉發給後端應用伺服器了,也可以是一個靜态首頁
# 第一個必選規則
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/;
}
#第三個規則就是通用規則,用來轉發動态請求到後端應用伺服器
#非靜态檔案請求就預設是動态請求,自己根據實際把握
#畢竟目前的一些架構的流行,帶.php,.jsp字尾的情況很少了
location / {
    proxy_pass http://tomcat:8080/
}

如果其他可以精确比對的路徑,也可以精确比對,這樣會加快Nginx處理請求。      
 

5、常用的正則比對:

 
. : 比對除換行符以外的任意字元
? : 重複0次或1次
+ : 重複1次或更多次
* : 重複0次或更多次
\d :比對數字
^ : 比對字元串的開始
$ : 比對字元串的介紹
{n} : 重複n次
{n,} : 重複n次或更多次
[c] : 比對單個字元c
[a-z] : 比對a-z小寫字母的任意一個
小括号()之間比對的内容,可以在後面通過$1來引用,$2表示的是前面第二個()裡的内容。正則裡面容易讓人困惑的是\轉義特殊字元。      
 

6、根據圖檔尺寸rewrite請求連結:

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

#将/images/bla_500x400.jpg的檔案請求,重寫到/resizer/bla.jpg?width=500&height=400位址,并會繼續嘗試比對location。      

7、域名重寫:

 
server {
        server_name  hfnginx.chinacloudapp.cn; #凡是通路hfnginx.chinacloudapp.cn都會重定向到http://www.baidu.com
        location / {
        root   html;
        index  index.html;
        rewrite  ^/  http://www.baidu.com;
    } 
}      
 

8、完整的例子引用:

 
http {
    # 定義image日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 開啟重寫日志
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重寫規則資訊
                error_log logs/rewrite.log notice; 
                # 注意這裡要用‘’單引号引起來,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面這條規則後面加上“last”參數,否則下面的set指令不會執行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定針對圖檔的日志格式,來分析圖檔類型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 應用前面定義的變量。判斷首先檔案在不在,不在再判斷目錄在不在,如果還不在就跳轉到最後一個url裡
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 圖檔不存在傳回特定的資訊
                return 404 "image not found\n";
        }
}      
 
上一篇: Get
下一篇: xml