nginx配置文件學習

nginx配置文件主要分爲六個區域:

main section、events section、http section、sever section、location section、upstream section。

main module:

主要控制子進程的所屬用戶/用戶組、派生子進程數、錯誤日誌位置/級別、pid位置、子進程優先級、進程對應cpu、進程能夠打開的文件描述符數目等。

user kingnet kingnet; 
worker_processes 4; 
error_log logs/error.log notice; 
pid logs/nginx.pid; 
# worker_priority -5; 
# worker_cpu_affinity 0001 0010 0100 1000; 
worker_rlimit_nofile 1024;
注:worker_cpu_affinity:指定進程對應cpu,上面配置是第一個進程對應cpu0,第二個進程對應cpu1,第三個進程對應cpu2,第四個進程對應cpu3,也可以指定一個進程對應多個cpu。比如0101表示進程對應cpu0/cpu2。
worker_rlimit_nofile:指定每個woker可以打開的文件描述符數目,一般和worker_connections的值是相同的。

event module:控制nginx處理連接的方式。

1234 events { 
    use epoll; 
    worker_connections 1024; 
}
注:use:使用網絡IO模型,epoll模型比select模型效率高很多。
worker_connections:每個worker能夠處理的最大連接數,取決於ulimit -n的值。
nginx併發連接數:<worker_processes*worker_connections。
HTTP Access模塊提供了一個簡單的基於host名稱的訪問控制。通過該模塊,可以允許或禁止指定的IP地址或IP地址段訪問某些虛擬主機或目錄
allow指令
語法:allow [address|CIDR|all]
使用環境:http,server,location
作用:允許指定的IP地址或IP地址段訪問某些虛擬主機或目錄
deny指令
語法:deny [address|CIDR|all]
使用環境:http,server,location
作用:禁止指定的IP地址或IP段訪問某些虛擬主機或目錄
匹配規則
控制規則按照聲明的順序進行檢查,首條匹配IP的訪問規則將被使用
演示用例
location  / {  
        deny 192.168.1.1;  
        allow  192.168.1.0/24;  
        deny all;  

解釋:
1.禁止192.168.1.1這個ip地址訪問
2.允許192.168.1.0/24這個地址段的ip訪問,但是由於192.168.1.1首先匹配deny,因此192.168.1.1是無法訪問的
3.當ip地址不匹配1,2兩條規則時,將禁止所有的ip地址訪問
http core主要用來控制處理客戶端的請求方式。
主要參數:
sendfile on;使用文件描述符拷貝數據,在內核狀態下完成 
tcp_nopush on;在sendfile開啓時有效 
keepalive_timeout 60; 長連接(一次連接可以連續發送多個數據包)超時時間 
tcp_nodelay on;在keepalive開啓時有效 
client_body_buffer_size 128k;  指定連接請求實體的緩衝區大小 
client_max_body_size 100m;    指定最大連接請求實體的大小 
client_header_buffer_size 64k; 指定連接請求實體頭部的緩衝區大小 
large_client_header_buffers 4 64k; 指定客戶端頭部比較大的使用緩衝區數量、大小 
server_tokens off; 關閉nginx的版本信息 
server_names_hash_max_size 1024;  名稱哈希表的最大值 

server_names_hash_bucket_size 256  名稱哈希表每個頁面的大小

注:依據/sys/devices/system/cpu/cpu0/cache/index1/size來決定hash表的大大小,一般是倍數關係。

server_name參數:將http請求的主機頭與參數值匹配
域名遵循優先級規則:
完整匹配的名稱
名稱開始於一個文件通配符:*.example.com
名稱結束於一個文件通配符:www.example.*
使用正則表達式的名稱。
如果沒有匹配到,遵循下面優先級
listen指令標記爲default的server字段
第一個出現listen的server字段。
error_page參數:爲錯誤代碼指定相應的錯誤頁面
error_page 401 402 403 404 /40x.html;
如果出現401、402、403、404錯誤則重定向到/40x.html頁面,這個頁面的位置需要結合匹配規則。
一般會爲錯誤頁面定義一個獨立的匹配規則,比如
location =/40x.html {
root html; #到html這個目錄尋找這個頁面
}

location參數:根據uri匹配。

語法規則: location [=|~|~*|^~] /uri/ { … }
= 開頭表示精確匹配
^~ 開頭表示uri以某個常規字符串開頭,理解爲匹配 url路徑即可。nginx不對url做編碼,因此請求爲/static/20%/aa,可以被規則^~ /static/ /aa匹配到(注意是空格)。
~ 開頭表示區分大小寫的正則匹配
~*  開頭表示不區分大小寫的正則匹配
!~和!~*分別爲區分大小寫不匹配及不區分大小寫不匹配 的正則
/ 通用匹配,任何請求都會匹配到。
多個location配置的情況下匹配順序爲(參考資料而來,還未實際驗證,試試就知道了,不必拘泥,僅供參考):
首先匹配 =,其次匹配^~, 其次是按文件中順序的正則匹配,最後是交給 / 通用匹配。當有匹配成功時候,停止匹配,按當前匹配規則處理請求。
例子,有如下匹配規則:
location = / {
   #規則A
}
location = /login {
   #規則B
}
location ^~ /static/ {
   #規則C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #規則D
}
location ~* \.png$ {
   #規則E
}
location !~ \.xhtml$ {
   #規則F
}
location !~* \.xhtml$ {
   #規則G
}
location / {
   #規則H
}
那麼產生的效果如下:
訪問根目錄/, 比如http://localhost/ 將匹配規則A
訪問 http://localhost/login 將匹配規則B,http://localhost/register 則匹配規則H
訪問 http://localhost/static/a.html 將匹配規則C
訪問 http://localhost/a.gifhttp://localhost/b.jpg 將匹配規則D和規則E,但是規則D順序優先,規則E不起作用,而 http://localhost/static/c.png 則優先匹配到規則C
訪問 http://localhost/a.PNG 則匹配規則E,而不會匹配規則D,因爲規則E不區分大小寫。
訪問 http://localhost/a.xhtml 不會匹配規則F和規則G,http://localhost/a.XHTML不會匹配規則G,因爲不區分大小寫。規則F,規則G屬於排除法,符合匹配規則但是不會匹配到,所以想想看實際應用中哪裏會用到。
訪問 http://localhost/category/id/1111 則最終匹配到規則H,因爲以上規則都不匹配,這個時候應該是nginx轉發請求給後端應用服務器,比如FastCGI(php),tomcat(jsp),nginx作爲方向代理服務器存在。

所以實際使用中,個人覺得至少有三個匹配規則定義,如下:
#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裏是直接轉發給後端應用服務器了,也可以是一個靜態首頁
# 第一個必選規則
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中配置proxy_pass時,如果是按照^~匹配路徑時,要注意proxy_pass後的url最後的/,當加上了/,相當於是絕對根路徑,則nginx不會把location中匹配的路徑部分代理走;如果沒有/,則會把匹配的路徑部分也給代理走。

location ^~ /static_js/ 

proxy_cache js_cache; 
proxy_set_header Host js.test.com; 
proxy_pass http://js.test.com/; 
}
如上面的配置,如果請求的url是http://servername/static_js/test.html
會被代理成http://js.test.com/test.html
而如果這麼配置
location ^~ /static_js/ 

proxy_cache js_cache; 
proxy_set_header Host js.test.com; 
proxy_pass http://js.test.com; 
}
則會被代理到http://js.test.com/static_js/test.htm
當然,我們可以用如下的rewrite來實現/的功能
location ^~ /static_js/ 

proxy_cache js_cache; 
proxy_set_header Host js.test.com; 
rewrite /static_js/(.+)$ /$1 break; 
proxy_pass http://js.test.com; 

一些可用的全局變量:

$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri

例如: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:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

ReWrite語法

nginx的rewrite格式是:rewrite regex replacement flag 
rewrite可以放在server, location 和 if 模塊中。

nginx rewrite指令執行順序:

1.執行server塊的rewrite指令(這裏的塊指的是server關鍵字後{}包圍的區域,其它xx塊類似)
2.執行location匹配
3.執行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件
如果循環超過10次,則返回500 Internal Server Error錯誤

其中flag標記有四種格式:
last – 相當於Apache中的L
break – 中止Rewirte,不在繼續匹配
redirect – 返回臨時重定向的HTTP狀態302,相當於Apache中的R
permanent – 返回永久重定向的HTTP狀態301,相當於Apache中的R=301

1、下面是可以用來判斷的表達式:
-f和!-f用來判斷是否存在文件
-d和!-d用來判斷是否存在目錄
-e和!-e用來判斷是否存在文件或目錄
-x和!-x用來判斷文件是否可執行

nginx 的 upstream目前支持 5 種分配方式

1、輪詢(默認)
每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動剔除。
2、weight
指定輪詢機率,weight和訪問比率成正比,用於後端服務器性能不均的情況,默認爲1。
例如:
upstream bakend {
    server 192.168.159.10 weight=10;
    server 192.168.159.11 weight=10;
}
3、ip_hash
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決session的問題。
例如:
upstream resinserver{
    ip_hash;
    server 192.168.159.10:8080;
    server 192.168.159.11:8080;
}
4、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream resinserver{
    server server1;
    server server2;
    fair;
}
5、url_hash(第三方)
按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
例:在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法
upstream resinserver{
    server squid1:3128;
    server squid2:3128;
    hash $request_uri;
    hash_method crc32;
}

在http節點裏添加:
#定義負載均衡設備的 Ip及設備狀態
upstream myServer {   
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;
}
#在需要使用負載的Server節點下添加
proxy_pass http://myServer;
#一個均衡服務器可配置多項,用空格隔開

upstream 每個設備的狀態:
down 表示單前的server暫時不參與負載
weight  默認爲1.weight越大,負載的權重就越大。
max_fails :允許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤
fail_timeout:max_fails 次失敗後,暫停的時間。
backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。
Nginx還支持多組的負載均衡,可以配置多個upstream  來服務於不同的Server.
配置負載均衡比較簡單,但是最關鍵的一個問題是怎麼實現多臺服務器之間session的共享
下面有幾種方法(以下內容來源於網絡,第四種方法沒有實踐.)
1) 不使用session,換作cookie
如果程序邏輯不復雜,將session都改成cookie
2) 應用服務器自行實現共享
可以用數據庫或memcached來保存session,它的效率是不會很高的,不適用於對效率 要求高的場合。
3) ip_hash
nginx中的ip_hash技術能夠將某個ip的請求定向到同一臺後端,這樣一來這個ip下的某個客戶端和某個後端就能建立起穩固的session,ip_hash是在upstream配置中定義的:
upstream backend {
server 127.0.0.1:8080 ;
server 127.0.0.1:9090 ;
ip_hash;
}
ip_hash是容易理解的,但是因爲僅僅能用ip這個因子來分配後端,因此ip_hash是有缺陷的,不能在一些情況下使用:
1、nginx不是最前端的服務器。ip_hash要求nginx一定是最前端的服務器,否則nginx得不到正確ip,就不能根據ip作hash。譬如使用的是squid爲最前端,那麼nginx取ip時只能得到squid的服務器ip地址,用這個地址來作分流是肯定錯亂的。
2、nginx的後端還有其它方式的負載均衡。假如nginx後端又有其它負載均衡,將請求又通過另外的方式分流了,那麼某個客戶端的請求肯定不能定位到同一臺session應用服務器上。這麼算起來,nginx後端只能直接指向應用服務器,或者再搭一個squid,然後指向應用服務器。最好的辦法是用location作一次分流,將需要session的部分請求通過ip_hash分流,剩下的走其它後端去。

client_max_body_size 300m;             //允許客戶端請求的最大的單個文件字節數  

client_body_buffer_size 128k;        //緩存區代理用戶端文件字節數 
client_body_temp_path /dev/shm/client_body_temp;     //請求試圖寫入到緩存文件的目錄路徑 
proxy_connect_timeout600;              //和後端服務器連接的超時時間, 
proxy_read_timeout 600;                  //連接成功等待後端相應的時間,默認是60S 
proxy_send_timeout 600;             //後端服務器的回傳時間,規定服務器在一定的時間內傳送完。 
proxy_buffer_size 16k;                  //代理服務器的緩存文件頭部文件大小,默認是4K 
proxy_buffers 4 32k;                    //後端真是服務器的數量和大小 
proxy_busy_buffers_size 64k;            //當系統忙事,申請更大proxy_buffer 
proxy_temp_file_write_size 64k;         //寫入臨時目錄的文件大小 
proxy_temp_path /dev/shm/proxy_temp;    //指定一個目錄來緩存比較大的代理請求 

proxy_pass http://cluster/;       //指定需要代理的URL, 
proxy_redirect off;         //如果需要從後端打開location和Refresh字段,可以開啓。 也就是說後端還有代理服務器時,需要打開
proxy_set_header X-Real-IP $remote_addr;           //允許將發送到後端的服務器請求重新定義或者增加一個字段,這個可以是變量也是文本組合。 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      //聯繫下面PS中所寫,在後端web中就算加上$http_x_Forwarded_for這條,也得不到用戶的IP,所以在                                                              nginx反向代理添加Header頭信息 X-Forwarded-For在配合後端服務器日誌文件的$http_x_Forwarded_for這條就可以獲得用戶的IP地址了。 
proxy_set_header Host $host;               //首先說明 proxy_set_header 指令在向反向代理的後端Web服務器發起請求時添加指定的 Header頭信息,後端web服務器有多個基於                                                                         域名的虛擬主機時,通過頭信息Host,用於指定請求的域名,這樣後端web才能識別反向代理請求哪個虛擬主機處理。 
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503  
http_504 http_404; 服務器頭部超時相應的各種狀態 

例子:

    upstream cluster { 
             server 192.168.100.238:80 weight=8 max_fails=2 fail_timeout=30s; 
             server 192.168.100.248:80 weight=8 max_fails=2 fail_timeout=30s; 
         }   

    server { 
        listen       80; 
        server_name  localhost; 
        location / { 
            root   html; 
            index  index.html index.htm; 
   ...

nginx fastcgi和gzip模塊
fastcgi模塊:nginx協同fastcgi工作
fastcgi_connect_timeout 200; 
fastcgi_send_timeout    200; 
fastcgi_read_timeout    200; 
fastcgi_buffer_size 4k; 
fastcgi_buffers 16 4k; 
fastcgi_busy_buffers_size 8k; 
fastcgi_max_temp_file_size 16k; 
fastcgi_intercept_errors on; php返回錯誤給nginx
說明:超時時間可以設置的大一些,緩衝區大小也可以設置大一些。
gzip模塊:數據壓縮傳輸
gzip  on; 
gzip_min_length 1k; 
gzip_buffers 8 8k; 
gzip_comp_level 2; 
gzip_types text/plain application/x-javascript text/css application/xml; 

gzip_vary on;



rewirite實例:

由於rewrite執行效率比較低,通常用return語句替代,如:

rewrite  (.*)  http://www.example.org$1;

改爲

retrun 301 https://www.example.org$request_uri;


Redirect語法

server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ “^star\.igrow\.cn$&quot {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
防盜鏈
location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
根據文件類型設置過期時間
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}
禁止訪問某個目錄
location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}

多目錄轉成參數
abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2
if ($host ~* (.*)\.domain\.com) {
set $sub_name $1;   
rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
}
目錄對換
/123456/xxxx -> /xxxx?id=123456
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
例如下面設定nginx在用戶使用ie的使用重定向到/nginx-ie目錄下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
目錄自動加“/”
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
禁止htaccess
location ~/\.ht {
         deny all;
     }
禁止多個目錄
location ~ ^/(cron|templates)/ {
         deny all;
break;
     }
禁止以/data開頭的文件
可以禁止/data/下多級目錄下.log.txt等請求;
location ~ ^/data {
         deny all;
     }
禁止單個目錄
不能禁止.log.txt能請求
location /searchword/cron/ {
         deny all;
     }
禁止單個文件
location ~ /data/sql/data.sql {
         deny all;
     }
給favicon.ico和robots.txt設置過期時間;
這裏爲favicon.ico爲99天,robots.txt爲7天並不記錄404錯誤日誌
location ~(favicon.ico) {
                 log_not_found off;
expires 99d;
break;
     }
     location ~(robots.txt) {
                 log_not_found off;
expires 7d;
break;
     }
設定某個文件的過期時間;這裏爲600秒,並不記錄訪問日誌
location ^~ /html/scripts/loadhead_1.js {
                 access_log   off;
                 root /opt/lampp/htdocs/web;
expires 600;
break;
       }
文件反盜鏈並設置過期時間
這裏的return 412 爲自定義的http狀態碼,默認爲403,方便找出正確的盜鏈的請求
“rewrite ^/ http://leech.c1gstudio.com/leech.gif;”顯示一張防盜鏈圖片
“access_log off;”不記錄訪問日誌,減輕壓力
“expires 3d”所有文件3天的瀏覽器緩存
location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194;
if ($invalid_referer) {
    rewrite ^/ http://leech.c1gstudio.com/leech.gif;
    return 412;
    break;
}
                 access_log   off;
                 root /opt/lampp/htdocs/web;
expires 3d;
break;
     }
只充許固定ip訪問網站,並加上密碼
root  /opt/htdocs/www;
allow   208.97.167.194;
allow   222.33.1.2;
allow   231.152.49.4;
deny    all;
auth_basic "C1G_ADMIN";
auth_basic_user_file htpasswd;
將多級目錄下的文件轉成一個文件,增強seo效果
/job-123-456-789.html 指向/job/123/456/789.html
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
將根目錄下某個文件夾指向2級目錄
如/shanghaijob/ 指向 /area/shanghai/
如果你將last改成permanent,那麼瀏覽器地址欄顯是/location/shanghai/
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
上面例子有個問題是訪問/shanghai 時將不會匹配
rewrite ^/([0-9a-z]+)job$ /area/$1/ last;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
這樣/shanghai 也可以訪問了,但頁面中的相對鏈接無法使用,
如./list_1.html真實地址是/area/shanghia/list_1.html會變成/list_1.html,導至無法訪問。
那我加上自動跳轉也是不行咯
(-d $request_filename)它有個條件是必需爲真實目錄,而我的rewrite不是的,所以沒有效果
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
知道原因後就好辦了,讓我手動跳轉吧
rewrite ^/([0-9a-z]+)job$ /$1job/ permanent;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
文件和目錄不存在的時候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}
域名跳轉
server
     {
             listen       80;
             server_name  jump.c1gstudio.com;
             index index.html index.htm index.php;
             root  /opt/lampp/htdocs/www;
             rewrite ^/ http://www.c1gstudio.com/;
             access_log  off;
     }
多域名轉向
server_name  www.c1gstudio.com www.c1gstudio.net;
             index index.html index.htm index.php;
             root  /opt/lampp/htdocs;
if ($host ~ "c1gstudio\.net") {
rewrite ^(.*) http://www.c1gstudio.com$1 permanent;
}
三級域名跳轉
if ($http_host ~* "^(.*)\.i\.c1gstudio\.com$") {
rewrite ^(.*) http://top.yingjiesheng.com$1;
break;
}
域名鏡向
server
     {
             listen       80;
             server_name  mirror.c1gstudio.com;
             index index.html index.htm index.php;
             root  /opt/lampp/htdocs/www;
             rewrite ^/(.*) http://www.c1gstudio.com/$1 last;
             access_log  off;
     }
某個子目錄作鏡向
location ^~ /zhaopinhui {
  rewrite ^.+ http://zph.c1gstudio.com/ last;
  break;
     }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章