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