nginx的基本詳解
nginx簡介
Nginx是lgor Sysoev為俄羅斯訪問量第二的rambler.ru站點設計開發的。從2004年發布至今,憑借開源的力量,已經接近成熟與完善。Nginx功能豐富,可作為HTTP服務器,也可作為反向代理服務器,郵件服務器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。並且支持很多第三方的模塊擴展。
nginx可以作為反向代理、負載均衡和web緩存使用,本節主要講解nginx的負載均衡功能,按照不同的負載策略可以分發到不同的後端服務器。負載均衡的結構圖如下圖所示:
配置文件詳解
1、全局塊
配置影響nginx全局的指令。一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日誌存放路徑,配置文件引入,允許生成worker process數等。
user 語法: user user [group] 缺省值: nobody nobody 指定Nginx Worker進程運行用戶,默認是nobody帳號。 error_log 語法: error_log file [ debug | info | notice | warn | error | crit ] 缺省值: ${prefix}/logs/error.log 指定錯誤日誌的存放位置和級別。 include 語法: include file | * 缺省值: none include 指令還支持像下面配置一樣的全局包含的方法,例如包含一個目錄下所有以".conf"結尾的文件: include vhosts/*.conf; pid 語法: pid file 進程id存儲文件。可以使用 kill -HUP cat /var/log/nginx.pid/ 對Nginx進行配置文件重新加載。 worker_processes 語法: worker_processes number 缺省值: 1,指定工作進程數。nginx可以使用多個worker進程(建議與本機CPU核心數一致)。
實例
user root root; worker_processes 24; #error_log logs/error.log; #error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid;
2、events塊
配置影響nginx服務器或與用戶的網絡連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啟多個網絡連接序列化等。
events { use epoll; 使用epoll的I/O 模型。linux建議epoll,FreeBSD建議采用kqueue,window下不指定。 補充說明:與apache相類,nginx針對不同的操作系統,有不同的事件模型 A)標準事件模型 Select、poll屬於標準事件模型,如果當前系統不存在更有效的方法,nginx會選擇select或poll B)高效事件模型 Kqueue:使用於FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用雙處理器的MacOS X系統使用kqueue可能會造成內核崩潰。 Epoll:使用於Linux內核2.6版本及以後的系統。 /dev/poll:使用於Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。 Eventport:使用於Solaris 10。 為了防止出現內核崩潰的問題, 有必要安裝安全補丁。 worker_connections 204800; 每個工作進程的最大連接數量。根據硬件調整,和前面工作進程配合起來用,盡量大,但是別把cpu跑到100%就行。每個進程允許的最多連接數,理論上每臺nginx服務器的最大連接數為。worker_processes*worker_connections keepalive_timeout 60; keepalive超時時間。 client_header_buffer_size 4k; 客戶端請求頭部的緩沖區大小。這個可以根據你的系統分頁大小來設置,一般一個請求頭的大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置為分頁大小。 分頁大小可以用命令getconf PAGESIZE 取得。 open_file_cache max=65535 inactive=60s; #這個是指多長時間檢查一次緩存的有效信息。 #語法:open_file_cache_valid time 默認值:open_file_cache_valid 60 使用字段:http, server, location 這個指令指定了何時需要檢查open_file_cache中緩存項目的有效信息. open_file_cache_valid 80s; #open_file_cache指令中的inactive參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在inactive時間內一次沒被使用,它將被移除。 open_file_cache_min_uses 1; #語法:open_file_cache_min_uses number 默認值:open_file_cache_min_uses 1 使用字段:http, server, location 這個指令指定了在open_file_cache指令無效的參數中一定的時間範圍內可以使用的最小文件數,如果使用更大的值,文件描述符在cache中總是打開狀態. open_file_cache_errors on; #語法:open_file_cache_errors on | off 默認值:open_file_cache_errors off 使用字段:http, server, location 這個指令指定是否在搜索一個文件是記錄cache錯誤. }
實例
events { worker_connections 65535; }
3、http塊
可以嵌套多個server,配置代理,緩存,日誌定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日誌自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。
1)http中的全局變量
http { include mime.types; 設定mime類型,類型由mime.type文件定義 default_type application/octet-stream; log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘ ‘$status $body_bytes_sent "$http_referer" ‘ ‘"$http_user_agent" "$http_x_forwarded_for"‘; log_format log404 ‘$status [$time_local] $remote_addr $host$request_uri $sent_http_location‘; 日誌格式設置。 $remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址; $remote_user:用來記錄客戶端用戶名稱; $time_local: 用來記錄訪問時間與時區; $request: 用來記錄請求的url與http協議; $status: 用來記錄請求狀態;成功是200, $body_bytes_sent :記錄發送給客戶端文件主體內容大小; $http_referer:用來記錄從那個頁面鏈接訪問過來的; $http_user_agent:記錄客戶瀏覽器的相關信息; 通常web服務器放在反向代理的後面,這樣就不能獲取到客戶的IP地址了,通過$remote_add拿到的IP地址是反向代理服務器的iP地址。反向代理服務器在轉發請求的http頭信息中,可以增加x_forwarded_for信息,用以記錄原有客戶端的IP地址和原來客戶端的請求的服務器地址。 access_log logs/host.access.log main; access_log logs/host.access.404.log log404; 用了log_format指令設置了日誌格式之後,需要用access_log指令指定日誌文件的存放路徑; server_names_hash_bucket_size 128; #保存服務器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。參數hash bucket size總是等於hash表的大小,並且是一路處理器緩存大小的倍數。在減少了在內存中的存取次數後,使在處理器中加速查找hash表鍵值成為可能。如果hash bucket size等於一路處理器緩存的大小,那麽在查找鍵的時候,最壞的情況下在內存中查找的次數為2。第一次是確定存儲單元的地址,第二次是在存儲單元中查找鍵 值。因此,如果Nginx給出需要增大hash max size 或 hash bucket size的提示,那麽首要的是增大前一個參數的大小. client_header_buffer_size 4k; 客戶端請求頭部的緩沖區大小。這個可以根據你的系統分頁大小來設置,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置為分頁大小。分頁大小可以用命令getconf PAGESIZE取得。 large_client_header_buffers 8 128k; 客戶請求頭緩沖大小。nginx默認會用client_header_buffer_size這個buffer來讀取header值,如果header過大,它會使用large_client_header_buffers來讀取。 open_file_cache max=102400 inactive=20s; 這個指令指定緩存是否啟用。 例: open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; 語法:open_file_cache_valid time 默認值:open_file_cache_valid 60 使用字段:http, server, location 這個指令指定了何時需要檢查open_file_cache中緩存項目的有效信息. open_file_cache_min_uses 2; 語法:open_file_cache_min_uses number 默認值:open_file_cache_min_uses 1 使用字段:http, server, location 這個指令指定了在open_file_cache指令無效的參數中一定的時間範圍內可以使用的最小文件數,如果使用更大的值,文件描述符在cache中總是打開狀態. open_file_cache_errors on; 語法:open_file_cache_errors on | off 默認值:open_file_cache_errors off 使用字段:http, server, location 這個指令指定是否在搜索一個文件是記錄cache錯誤. client_max_body_size 300m; 設定通過nginx上傳文件的大小 sendfile on; sendfile指令指定 nginx 是否調用sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設為on。如果用來進行下載等應用磁盤IO重負載應用,可設置為off,以平衡磁盤與網絡IO處理速度,降低系統uptime。 tcp_nodelay on; tcp_nopush on; 此選項允許或禁止使用socke的TCP_CORK的選項,此選項僅在使用sendfile的時候使用 keys_zone=cache_one:200m inactive=1d max_size=30g; #設置內存緩存空間大小為200MB,1天沒有被訪問的內容自動清除,硬盤緩存空間大小為30GB。 keepalive_timeout 120; keepalive超時時間。 client_body_buffer_size 512k; 如果把它設置為比較大的數值,例如256k,那麽,無論使用firefox還是IE瀏覽器,來提交任意小於256k的圖片,都很正常。如果註釋該指令,使用默認的client_body_buffer_size設置,也就是操作系統頁面大小的兩倍,
8k或者16k,問題就出現了。無論使用firefox4.0還是IE8.0,提交一個比較大,200k左右的圖片,都返回500 Internal Server Error錯誤 #http_proxy模塊
。。。。。。 #gzip模塊 。。。。。。 upstream bakend { 。。。。。。。 } #server模塊 。。。。。 }
2)gzip模塊
gzip_static on; gzip_http_version 1.0; gzip_proxied expired no-cache no-store private auth; gzip_vary on; gzip on; gzip_types text/plain text/css text/xml application/xml application/xml+rss application/json; gzip_min_length 1100; gzip_buffers 4 8k;
gzip on|off
# 默認值: gzip off
# 開啟或者關閉gzip模塊
gzip_static on|off
# nginx對於靜態文件的處理模塊
# 該模塊可以讀取預先壓縮的gz文件,這樣可以減少每次請求進行gzip壓縮的CPU資源消耗。該模塊啟用後,nginx首先檢查是否存在請求靜態文件的gz結尾的文件,如果有則直接返回該gz文件內容。為了要兼容不支持gzip的瀏覽器,啟用gzip_static模塊就必須同時保留原始靜態文件和gz文件。這樣的話,在有大量靜態文件的情況下,將會大大增加磁盤空間。我們可以利用nginx的反向代理功能實現只保留gz文件。
#可以google"nginx gzip_static"了解更多
gzip_comp_level 4
# 默認值:1(建議選擇為4)
# gzip壓縮比/壓縮級別,壓縮級別 1-9,級別越高壓縮率越大,當然壓縮時間也就越長(傳輸快但比較消耗cpu)。
gzip_buffers 4 16k
# 默認值: gzip_buffers 4 4k/8k
# 設置系統獲取幾個單位的緩存用於存儲gzip的壓縮結果數據流。 例如 4 4k 代表以4k為單位,按照原始數據大小以4k為單位的4倍申請內存。 4 8k 代表以8k為單位,按照原始數據大小以8k為單位的4倍申請內存。
# 如果沒有設置,默認值是申請跟原始數據相同大小的內存空間去存儲gzip壓縮結果。
gzip_types mime-type [mime-type ...]
# 默認值: gzip_types text/html (默認不對js/css文件進行壓縮)
# 壓縮類型,匹配MIME類型進行壓縮
# 不能用通配符 text/*
# (無論是否指定)text/html默認已經壓縮
# 設置哪壓縮種文本文件可參考 conf/mime.types
gzip_min_length 1k
# 默認值: 0 ,不管頁面多大都壓縮
# 設置允許壓縮的頁面最小字節數,頁面字節數從header頭中的Content-Length中進行獲取。
# 建議設置成大於1k的字節數,小於1k可能會越壓越大。 即: gzip_min_length 1024
gzip_http_version 1.0|1.1
# 默認值: gzip_http_version 1.1(就是說對HTTP/1.1協議的請求才會進行gzip壓縮)
# 識別http的協議版本。由於早期的一些瀏覽器或者http客戶端,可能不支持gzip自解壓,用戶就會看到亂碼,所以做一些判斷還是有必要的。
# 註:99.99%的瀏覽器基本上都支持gzip解壓了,所以可以不用設這個值,保持系統默認即可。
# 假設我們使用的是默認值1.1,如果我們使用了proxy_pass進行反向代理,那麽nginx和後端的upstream server之間是用HTTP/1.0協議通信的,如果我們使用nginx通過反向代理做Cache Server,而且前端的nginx沒有開啟gzip,同時,我們後端的nginx上沒有設置gzip_http_version為1.0,那麽Cache的url將不會進行gzip壓縮
gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] ...
# 默認值:off
# Nginx作為反向代理的時候啟用,開啟或者關閉後端服務器返回的結果,匹配的前提是後端服務器必須要返回包含"Via"的 header頭。
off - 關閉所有的代理結果數據的壓縮
expired - 啟用壓縮,如果header頭中包含 "Expires" 頭信息
no-cache - 啟用壓縮,如果header頭中包含 "Cache-Control:no-cache" 頭信息
no-store - 啟用壓縮,如果header頭中包含 "Cache-Control:no-store" 頭信息
private - 啟用壓縮,如果header頭中包含 "Cache-Control:private" 頭信息
no_last_modified - 啟用壓縮,如果header頭中不包含 "Last-Modified" 頭信息
no_etag - 啟用壓縮 ,如果header頭中不包含 "ETag" 頭信息
auth - 啟用壓縮 , 如果header頭中包含 "Authorization" 頭信息
any - 無條件啟用壓縮
gzip_vary on
# 和http頭有關系,加個vary頭,給代理服務器用的,有的瀏覽器支持壓縮,有的不支持,所以避免浪費不支持的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮
gzip_disable "MSIE [1-6]."
#禁用IE6的gzip壓縮,又是因為杯具的IE6。當然,IE6目前依然廣泛的存在,所以這裏你也可以設置為“MSIE [1-5].”
#IE6的某些版本對gzip的壓縮支持很不好,會造成頁面的假死,今天產品的同學就測試出了這個問題後來調試後,發現是對img進行gzip後造成IE6的假死,把對img的gzip壓縮去掉後就正常了為了確保其它的IE6版本不出問題,所以建議加上gzip_disable的設置
3)upstream模塊
作為負載均衡池,可以為一個請求分配多個負載,防止單臺服務器宕機後請求無法處理,負載均衡的策略有:輪詢、加權輪詢和哈希一致,配置如下:
#加權輪詢 upstream back_openaccess { server 10.159.39.136:12080 weight=2 max_fails=3 fail_timeout=10s; server 10.159.39.137:12080 weight=2 max_fails=3 fail_timeout=10s; } #ip_hash upstream back_openadmin { ip_hash; server 10.159.39.136:12081; server 10.159.39.137:12081; }
加權輪詢配置參數:
down 表示單前的server暫時不參與負載.
weight 默認為1.weight越大,負載的權重就越大。
max_fails :允許請求失敗的次數默認為1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤.
fail_timeout : max_fails次失敗後,暫停的時間。
backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。
max_conns:限制分配給某臺Server處理的最大連接數量,超過這個數量,將不會分配新的連接給它。默認為0,表示不限制。註意:1.5.9之後的版本才有這個配置
4)server模塊
server { listen 80; server_name "127.0.0.1"; root /kingdee/www/; #Open underscores_in_headers underscores_in_headers on; proxy_redirect off; include conf.d/*.conf; location /ngs { stub_status on; access_log on; } location /upss { check_status; access_log off; } }
listen:監聽端口,默認80,小於1024的要以root啟動。可以為listen
*:80
、liste
n
127.0.0.1:80
等形式。
server_name:服務器名,如localhost、www.example.com
,可以通過正則匹配。
root:設定響應的根目錄。
include:引入其他的配置文件。
underscores_in_headers:支持讀取非nginx標準的用戶自定義header的,但是需要在http或者server下開啟header。
proxy_redirect:語法:proxy_redirect [ default|off|redirect replacement ] ,默認值:proxy_redirect default ,修改被代理服務器返回的響應頭。例如:proxy_redirect http://localhost:8000/two/ http://frontend/one/;將Location字段重寫為http://frontend/one/。
location:根據請求的RUI設置配置,進行負載均衡。location中的配置參數如下:
1、proxy_set_header參數:語法為:proxy_set_header Field Value。常見的設置如:
proxy_set_header Host $proxy_host;
獲取nginx配置中的server_name值。
proxy_set_header X-Real-IP $remote_addr;
有了這個配置就可以在web服務器端獲得用戶的真實ip
proxy_set_header X-Forwarded-For $remote_addr;
我們先看看這裏有個X-Forwarded-For變量,這是一個squid開發的,用於識別通過HTTP代理或負載平衡器原始IP一個連接到Web服務器的客戶機地址的非rfc標準,如果有做X-Forwarded-For設置
的話,每次經過proxy轉發都會有記錄,格式就是client1, proxy1, proxy2,以逗號隔開各個地址,由於他是非rfc標準,所以默認是沒有的,需要強制添加,在默認情況下經過proxy轉發的請求,在後端看
來遠程地址都是proxy端的ip 。也就是說在默認情況下我們使用request.getAttribute("X-Forwarded-For")獲取不到用戶的ip,如果我們想要通過這個變量獲得用戶的ip,我們需要自己在nginx添加配置。
2、proxy_pass:轉發的代理路徑
情況一、location /test/ {
proxy_pass http://t6:8300;
}
情況二、location /test/ {
proxy_pass http://t6:8300/;
}
針對情況2,如果訪問url = http://server/test/test.jsp,則被nginx代理後,請求路徑會變為 http://proxy_pass/test.jsp,直接訪問server的根資源
針對情況1,如果訪問url = http://server/test/test.jsp,則被nginx代理後,請求路徑會便問http://proxy_pass/test/test.jsp,將test/ 作為根路徑,請求test/路徑下的資源
5)proxy_buffer模塊
proxy_buffer_size 256k; 設置從被代理服務器讀取的第一部分應答的緩沖區大小,通常情況下這部分應答中包含一個小的應答頭,默認情況下這個值的大小為指令proxy_buffers中指定的一個緩沖區的大小,不過可以將其設置為更小 proxy_buffers 4 256k; 設置用於讀取應答(來自被代理服務器)的緩沖區數目和大小,默認情況也為分頁大小,根據操作系統的不同可能是4k或者8k proxy_busy_buffers_size 256k;
proxy_connect_timeout 90; 後端服務器連接的超時時間_發起握手等候響應超時時間 proxy_read_timeout 180; 連接成功後_等候後端服務器響應時間_其實已經進入後端的排隊之中等候處理(也可以說是後端服務器處理請求的時間) proxy_send_timeout 180; 後端服務器數據回傳時間_就是在規定時間之內後端服務器必須傳完所有的數據 proxy_temp_file_write_size 256k; 設置在寫入proxy_temp_path時數據的大小,預防一個工作進程在傳遞文件時阻塞太長 proxy_temp_path /data0/proxy_temp_dir; proxy_temp_path和proxy_cache_path指定的路徑必須在同一分區
1. proxy_buffering
語法:proxy_buffering on|off
默認值:proxy_buffering 0n
該 指令開啟從後端被代理服務器的響應內容緩沖。如果緩沖區開啟,nginx假定被代理的後端服務器會以最快速度響應,並把內容保存在由指令 proxy_buffer_size 和 proxy_buffers指定的緩沖區裏邊.如果響應內容無法放在內存裏邊,那麽部分內容會被寫到磁盤上。如果緩沖區被關閉了,那麽響應內容會按照獲取 內容的多少立刻同步傳送到客戶端。nginx不嘗試計算被代理服務器整個響應內容的大小,nginx能從服務器接受的最大數據,是由指令 proxy_buffer_size指定的.對於基於長輪詢(long-polling)的Comet 應用來說,關閉 proxy_buffering 是重要的,不然異步響應將被緩存導致Comet無法工作。
2. proxy_buffers
語法:proxy_buffers 數量 大小
默認值:proxy_buffers 8 4k/8k
該指令設置緩沖區的大小和數量,從被代理的後端服務器取得的響應內容,會放置到這裏. 默認情況下,一個緩沖區的大小等於內存頁面大小,可能是4K也可能是8K,這取決於平臺。
3. proxy_buffer_size
語法:proxy_buffer_size the size
默認值:proxy_buffer_size 4k/8k
該指令設置緩沖區大小,從代理後端服務器取得的第一部分的響應內容,會放到這裏.小的響應header通常位於這部分響應內容裏邊.默認來說,該緩沖區大小等於指令 proxy_buffers所設置的;但是,你可以把它設置得更小.
4. proxy_busy_buffers_size
語法:proxy_busy_buffers_size 大小
默認值:proxy_busy_buffers_size proxy_buffer_size*2
buffer 工作原理
1. 所有的proxy buffer參數是作用到每一個請求的。每一個請求會安按照參數的配置獲得自己的buffer。proxy buffer不是global而是per request的。
2. proxy_buffering 是為了開啟response buffering of the proxied server,開啟後proxy_buffers和proxy_busy_buffers_size參數才會起作用。
3. 無論proxy_buffering是否開啟,proxy_buffer_size(main buffer)都是工作的,proxy_buffer_size所設置的buffer_size的作用是用來存儲upstream端response的header。
4. 在proxy_buffering 開啟的情況下,Nginx將會盡可能的讀取所有的upstream端傳輸的數據到buffer,直到proxy_buffers設置的所有buffer們 被寫滿或者數據被讀取完(EOF)。此時nginx開始向客戶端傳輸數據,會同時傳輸這一整串buffer們。同時如果response的內容很大的 話,Nginx會接收並把他們寫入到temp_file裏去。大小由proxy_max_temp_file_size控制。如果busy的buffer 傳輸完了會從temp_file裏面接著讀數據,直到傳輸完畢。
5. 一旦proxy_buffers設置的buffer被寫入,直到buffer裏面的數據被完整的傳輸完(傳輸到客戶端),這個buffer將會一直處 在busy狀態,我們不能對這個buffer進行任何別的操作。所有處在busy狀態的buffer size加起來不能超過proxy_busy_buffers_size,所以proxy_busy_buffers_size是用來控制同時傳輸到客戶 端的buffer數量的。4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。
Nginx的部分模塊
stub_status模塊
stub_status模塊主要用來展示nginx的狀態信息也就是nginx的統計信息。配置信息如下:
location /ngs { stub_status on; access_log on; }
在輸入域名/ngs後會展示nginx的統計信息如下:
Active connections: 當前nginx正在處理的活動連接數.
Server accepts handled requests request_time: nginx總共處理了13057 個連接,成功創建13057 握手(證明中間沒有失敗的),總共處理了11634 個請求,總共請求時間2230854。
Reading: nginx讀取到客戶端的Header信息數.
Writing: nginx返回給客戶端的Header信息數.
Waiting: 開啟keep-alive的情況下,這個值等於 active – (reading + writing),意思就是nginx已經處理完成,正在等候下一次請求指令的駐留連接。所以,在訪問效率高,請求很快被處理完畢的情況下,Waiting數比較多是正常的.如果reading +writing數較多,則說明並發訪問量非常大,正在處理過程中。
nginx的基本詳解