目錄
- 前言
- nginx配置說明
- 高層配置
- Events模塊
- HTTP 模塊
- gzip模塊設置
- 虛擬主機的配置
- 附錄: nginx配置文件詳解
- 更多參考
- 總結
前言
大部分web應用都使用了nginx做負載均衡服務器,下面總結了nginx.conf中一些可以微調的配置。需要注意一點,這不是一個全面的微調指南。這是一個簡單的預覽——那些可以通過微調來提高性能設置的概述。你的情況可能不同。
nginx配置說明
nginx.conf中主要分高層配置、Events模塊、HTTP 模塊三個模塊。下面依次介紹個模塊可以微調的配置。
高層配置
user admin; #定義Nginx運行的用戶 error_log ar/loginx/error.log info; #全局錯誤日志定義類型,[ debug | info | notice | warn | error | crit ] access_log off; #定義本虛擬主機的訪問日志 pid ar/runinx.pid; #進程文件 worker_processes auto; #nginx進程數 worker_rlimit_nofile 65535; #一個nginx進程打開的最多文件描述符數目
可以微調的配置:
- worker_processes:建議設置為等于CPU總核心數。
- worker_rlimit_nofile:理論值應該是最多打開文件數(系統的值ulimit -n)與nginx進程數相除,但是nginx分配請求并不均勻,所以建議與ulimit -n的值保持一致。
Events模塊
events {
use epoll; #設置用于復用客戶端線程的輪詢方法,[ kqueue | rtsig | epoll | /dev/poll | select | poll ]
worker_connections 65535; #單個進程最大連接數(最大連接數=連接數*進程數)
multi_accept on; #開啟后告訴nginx收到一個新連接通知后接受盡可能多的連接
}
可以微調的配置:
- use:如果你使用Linux 2.6+,你應該使用epoll。如果你使用BSD,你應該使用kqueue。
- worker_connections:設置可由一個worker進程同時打開的最大連接數。如果設置了上面提到的worker_rlimit_nofile,我們可以將這個值設得很高。記住,最大客戶數也由系統的可用socket連接數限制(~ 64K),所以設置不切實際的高沒什么好處。
HTTP 模塊
HTTP模塊控制著nginx http處理的所有核心特性,內容比較多,這里分批說明。
http{
server_tokens off; #開啟或關閉在錯誤信息的“Server”響應頭中輸出nginx版本號
include mime.types; #文件擴展名與文件類型映射表
default_type application/octet-stream; #默認文件類型
charset utf-8; #默認編碼
server_names_hash_bucket_size 128; #服務器名字的hash表大小
client_header_buffer_size 32k; #設置讀取客戶端請求頭部的緩沖容量
large_client_header_buffers 4 64k; #設置讀取客戶端請求超大請求的緩沖最大number(數量)和每塊緩沖的size(容量)
client_max_body_size 8m; #設定請求緩存
sendfile on; #開啟高效文件傳輸模式
autoindex on; #開啟目錄列表訪問,合適下載服務器,默認關閉。
tcp_nopush on; #開啟或者關閉nginx在FreeBSD上使用TCP_NOPUSH套接字選項
tcp_nodelay on; #開啟或關閉nginx使用TCP_NODELAY選項的功能
keepalive_timeout 120; #長連接超時時間,單位是秒
reset_timedout_connection on; #開啟或關閉重置超時連接的功能
...
}
可以微調的配置:
- sendfile:指定nginx是否調用sendfile函數來輸出文件,對于普通應用設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為off,以平衡磁盤與網絡I/O處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成off。
- tcp_nopush: 選項僅在使用sendfile的時候才開啟。告訴nginx在一個數據包里發送所有頭文件,而不一個接一個的發送。
- tcp_nodelay:這個選項僅在將連接轉變為長連接的時候才被啟用。告訴nginx不要緩存數據,而是一段一段的發送——當需要及時發送數據時,就應該給應用設置這個屬性,這樣發送一小塊數據信息時就不能立即得到返回值。
- reset_timedout_connection:重置連接是這樣執行的:關閉套接字以前,設置SO_LINGER選項的超時值為0, 那么當關閉套接字時,nginx向客戶端發送TCP RST,并且釋放此套接字占用的所有內存。 這樣可以避免某個已關閉的套接字長時間處于FIN_WAIT1狀態,并占用內存緩沖區。應該注意的事,超時的長連接仍然是正常關閉。
- client_header_buffer_size:設置讀取客戶端請求頭部的緩沖容量。 對于大多數請求,1K的緩沖足矣。 但如果請求中含有的cookie很長,或者請求來自WAP的客戶端,可能請求頭不能放在1K的緩沖中。 如果從請求行,或者某個請求頭開始不能完整的放在這塊空間中,那么nginx將按照 large_client_header_buffers指令的配置分配更多更大的緩沖來存放。
- large_client_header_buffers:HTTP請求行的長度不能超過一塊緩沖的容量,否則nginx返回錯誤414 (Request-URI Too Large)到客戶端。 每個請求頭的長度也不能超過一塊緩沖的容量,否則nginx返回錯誤400 (Bad Request)到客戶端。 緩沖僅在必需是才分配,默認每塊的容量是8K字節。 即使nginx處理完請求后與客戶端保持入長連接,nginx也會釋放這些緩沖。
gzip模塊設置
gzip on; #開啟gzip壓縮輸出
gzip_min_length 1k; #最小壓縮長度
gzip_buffers 4 16k; #壓縮緩沖區
gzip_http_version 1.0; #壓縮版本
gzip_comp_level 2; #壓縮等級
gzip_types text/plain application/x-javascript text/css application/xml; #壓縮類型。
limit_zone crawler $binary_remote_addr 10m; #開啟限制IP連接數的時候需要使用
upstream 127.0.0.1 { #負載均衡
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}
可以微調的配置:
- upstream:upstream負載均衡,weight是權重,可以根據機器配置定義權重。weigth參數表示權值,權值越高被分配到的幾率越大。
虛擬主機的配置
server{
listen 80; #監聽端口
server_name www.cainiao.com cainiao.com; #域名可以有多個,用空格隔開
location / { #對 "/" 啟用反向代理
proxy_pass 127.0.0.1:8080; #設置后端服務器的協議和地址
#root /home/admin/pac; #請求根目錄
#index index.html index.htm; #主頁
#后端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可選。
proxy_set_header Host $host;
client_max_body_size 10m; #允許客戶端請求的最大單文件字節數
client_body_buffer_size 128k; #緩沖區代理緩沖用戶端請求的最大字節數,
proxy_connect_timeout 90; #nginx跟后端服務器連接超時時間(代理連接超時)
proxy_send_timeout 90; #后端服務器數據回傳時間(代理發送超時)
proxy_read_timeout 90; #連接成功后,后端服務器響應時間(代理接收超時)
proxy_buffer_size 4k; #設置代理服務器(nginx)保存用戶頭信息的緩沖區大小
proxy_buffers 4 32k; #proxy_buffers緩沖區,網頁平均在32k以下的設置
proxy_busy_buffers_size 64k; #高負荷下緩沖大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #設定緩存文件夾大小,大于這個值,將從upstream服務器傳
}
}
附錄: nginx配置文件詳解
//定義一個用戶以及對應的組
user admin admin
//定義nginx worker 進程的數量,設置為auto,就是默認和CPU個數一致
work_processess auto
//與上面的指令協同工作。他可以讓你的worker進程影響CPU內核,數字序列和work進程一樣多
work_cpu_affinity auto
//nginx錯誤日志,有debug,warn, error等五個等級
error_log /home/admin/web/logs/error.log warn
//用于存放nginx守護進程的PID文件路徑, 里面記錄了主進程的pid號
pid /home/admin/nginx/logs/nginx-search.pid;
//定義每個work進程的內核文件大小
worker_rlimit_core 1024M
//定義一個worker進程可以同時處理的文件數量
worker_rlimit_nofile 100000
//與events模塊一起提供的指令可以用來配置網絡機制,指令參數對nginx性能產生影響
events{
//定義一個worker進程能夠同時連接的數量
worker_connectins 10240;
use epoll;
}
//該區段嵌入配置文件的根部,在該區段允許定義指令和嵌入HTTP相關模塊
-http{
//隱藏nginx的版本號, 出現400 500 頁面時候不會顯示nginx服務器的版本號,避免漏洞
server_token off;
//文件包含指令; mime.type文件里面保存了nginx的MIME類型; 里面其實也是一個types{...}
include mime.type
// 該指令允許你在MIME類型和文件擴展名之間建立聯系, 可以補充mime.type文件沒有對應關系
types{
application/x-compress .Z;
application/x-gzip .gz .tgz;
application/x-httpd-php .php .html;
}
//定義默認的MIME類型,如果文件擴展名與mime.type中類型都不匹配,就將該值寫進content-type
default_type text/plain;
//如果該指令被啟用,Nginx將使用sendFile 內核來調用文件傳遞。如果禁用,那么nginx將自己處理文件傳遞
sendfile on;
//該選項只用于sendfile已啟動的情況。若為on, 那么nginx將嘗試單個TCP數據包中發送整個HTTP響應頭
tcp_nopush on;
//keep-alive能夠使客戶端到服務器的鏈接在一定時間內持續有效,在這個時間內,客戶端對服務器的訪問不需要再次建立鏈接
keepalive_timeout 0;
client_header_timeout 30s;
//指定持有客戶端請求主體的緩存大小,如果超過這個大小,那么主體將被寫到磁盤
client_body_buffer_size 32k;
/**gzip是一種壓縮技術。經過gzip壓縮后頁面大小可以變為原來的30%甚至更小**/
//開啟gzip模塊 off為關閉
gzip on;
//識別http的協議版本
gzip_http_version 1.0;
//gzip壓縮比,1壓縮比最小,9壓縮比最大,相應的速度也會變慢
gzip_comp_level 6;
// 設置允許壓縮的頁面最小字節數,默認為0,頁面多大都壓縮
gzip_min_length 1024;
//啟用或者禁用gzip壓縮,針對代理服務器上接收到的相應體
gzip_proxied any;
//有的瀏覽器支持壓縮,有的不支持,為了避免浪費,根據HTTP頭來判斷是否需要壓縮
gzip_vary on;
gzip_disable msie6; //???
//設置系統獲取幾個單位的緩存用于存儲gzip的壓縮結果數據流
gzip_buffers 64 8k;
//匹配mime類型進行壓縮,無論是否制定“text/html”類型總會被壓縮
gzip_types text/xml text/plain text/css application/javascript application/x- javascript application/rss+xml;
//定義文檔的根目錄,該目錄包含你希望為訪問者提供的內容
root /home/admin/web/htdocs;
//定義一個默認的頁面,如果請求中沒有指定文件名,nginx就會使用該頁面提供服務。
index index.html index.php index.htm;
//proxy_set_header nginx作為反向代理服務器,將請求轉發給后端真實服務器,如果不行host的重寫,所有的真是服務器都會誤認為是nginx服務器發送的請求。 proxy_set_header就是用于將客戶端真實的host, ip信息,傳送給后端服務器。 http://www.ithov.com/linux/109626_3.shtml
proxy_set_header Host $host;
//在這里X-Real-IP是一個自定義的變量名,名字可以隨意取,在web端可以用request.getAttribute("X-Real-IP") 獲取IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Web-Server-Type nginx;
// 如果需要修改從被代理服務器傳來的應答頭中的”Location”和”Refresh”字段,可以用指令設置。
proxy_redirect off;
proxy_buffers 128 8k;
proxy_intercept_errors on;
//開啟或者禁用404沒有找到HTTP錯誤。例如,如果日志中充滿了404錯誤,卻由于 robots.txt文件,那么你可以將這個選項關閉掉;
log_not_found off;
// 用于定義發生制定的錯誤代碼時候,使用errror_page來定義服務器的行為。最簡單的形式是使用一個錯誤代碼改變URI
error_page 403 404 405 http://www.jd.com/home/error.php;
error_page 500 501 502 http://www.jd.com/home/error2.php;
expires_by_types modified +3y image/gif image/jpeg image/jpg text/css application/x-shockwave-flash;
//限制被定義的zone的請求總數,$binary_remote_addr用于區分客戶端, rate表示每秒的請求數(r/s)或者每分鐘請求數(r/m)
limit_req_zone $binary_remote_addr zone=one:100m rate=5r/s;
#virtual servers
server{
//指定用于提供web服務站點監聽的套接字所使用的IIP和端口
listen 80;
//在server區段指定一個或者多個主機名(hostname), Nginx接收到HTTP請求以后,會與所有server區段相比較,然后找到與客戶端請求header中Host匹配的server區段。如果沒有與客戶端匹配的server區段,nginx會選擇第一個server區段。該指令接受通配符
server_name wenda.taobao.com q.etao.com wenda.etao.com;
// 定義一個日志模板用于描述訪問日志中一條包含的內容,該模板由access_log指令使用
log_format eformat ' remoteaddr r e m o t e a d d r request_time_usec remoteuser[ r e m o t e u s e r [ time_local] ' '"requestmethodhttp:// r e q u e s t m e t h o d h t t p : / / hostrequesturi" r e q u e s t u r i " status $body_bytes_sent '
'" httpreferer"" h t t p r e f e r e r "" http_user_agent"';
//該指令定了訪問日志文件的路徑
access_log "pipe: /opt/taobao/install/cronolog/sbin/cronolog /home/admin/web/logs/search/%Y/%m/%d/access-%Y-%m-%d_%H.log" eformat;
//定義文檔的根目錄,該目錄包含你希望為訪問者提供的內容
root /home/admin/web/htdocs/;
//limit_req_one 同上,burst定義了最大可能的突發請求, 在一定程度上,burst定義的值就是只能同時接受最大數量的請求值
limit_req zone=one burst=5 nodelay;
//set_by_lua指令支持通過一小段用戶Lua代碼來計算出一個結果,然后復制給Nginx 變量,和set指令相似
//Lua代碼中,通過ngx.var.VARIABLE來讀取Nginx的變量; 下面的一段代碼是用于修復comons-fileupload-1.0版本的漏洞
set_by_lua invalid_ct 'local ct = ngx.var.http_content_type if ct and #ct >= 2049 then return 1 else return 0 end'; if ( invalid_ct 'local ct = ngx.var.http_content_type if ct and #ct >= 2049 then return 1 else return 0 end'; if ( invalid_ct = '1') { return 400; }
//根據host 進行跳轉的判斷
if ($host = 'q.jd.com'){
//該指令允許你對當前請求的URI 進行重寫,因此對客戶端的請求會被重新設置
//格式為 rewrite regexp replacement 【flag】 ;; flag 包含:last, break,redirect, permanent
// regexp 是URI正則表達式,他的目的是匹配后面的replacement
//permanent 返回301 重定向響應,被替代的URI作為location頭的值(瀏覽器顯示跳轉之后URL地址)
rewrite ^/(.*) http://wenda.jd.com/ http://wenda.jd.com/1 permanent;
}
location ~ .(do|htm|vhtml|service|jhtml)$ {
//在配置proxy_pass的時候需要注意:http://dmouse.iteye.com/blog/1880474
//符合location 樣式跳轉地址; 這個指令設置被代理服務器的地址和被映射的URI,地址可以使用主機名或IP加端口號的形式。
proxy_pass http://127.0.0.1:8000;
//拒絕訪問的IP字段
deny 113.59.*.*;
}
}
更多參考
更詳細的模塊參數請參考:http://nginx.org/cn/docs/
核心模塊:http://nginx.org/cn/docs/http/ngx_http_core_module.html






