nginx優(yōu)化
充分發(fā)揮Nginx的高效性和穩(wěn)定性,對(duì)于Nginx優(yōu)化非常重要。下面主要是從編譯安裝、第三方插件、系統(tǒng)內(nèi)核等三方面介紹。
編譯安裝過(guò)程優(yōu)化
1、減小Nginx編譯后的文件大小
在編譯Nginx時(shí),默認(rèn)是以debug模式進(jìn)行,而在debug模式下會(huì)插入很多跟蹤和ASSERT之類(lèi)的信息,編譯完后,一個(gè)Nginx要有好幾兆字節(jié)。在編譯前取消debug模式,編譯完成后Nginx只有幾百千字字節(jié),因此,在編譯之前,修改相關(guān)源碼,取消debug模式。
在Nginx源碼文件中,找到源碼目錄下的auto/cc/gcc文件,在打開(kāi)后在其中找到如下幾行:

注釋或者刪除這兩行,就可以取消debug模式。
2、為特定的CPU指定CPU編譯類(lèi)型編譯優(yōu)化。
在編譯Nginx,默認(rèn)的GCC編譯參數(shù)是“-O”,需要優(yōu)化GCC編譯,可以使用這兩個(gè)參數(shù)。
--with-cc-opt="-O3"
--with-cpu-opt=CPU #位特定的CPU編譯,有效值包括:Pentium、pentiumpro、pentium3、Pentium4、athlon、Opteron、amd64、sparc32、sparc64、ppc64
要確定CPU類(lèi)型,可以通過(guò)以下命令:
cat /proc/cpuinfo| grep "model name"
3、隱藏版本號(hào)和軟件名
vi src/core/nginx.h
- #define NGINX_VERSION "7.0"
- #defineNGINX_VER "IIS/" NGINX_VERSION #這里修改的是你想要修改的軟件名稱(chēng)
修改HTTP頭信息中的connection字段,防止回顯具體版本號(hào)
通用http頭,通用頭包含請(qǐng)求和響應(yīng)消息都支持的頭,通用頭包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。對(duì)通用頭的擴(kuò)展要求通訊雙方都支持此擴(kuò)展,如果存在不支持的通用頭,一般將會(huì)作為實(shí)體頭處理。那么也就是說(shuō)有部分設(shè)備,或者是軟件,能獲取到connection,部分不能,要隱藏就要徹底!
vi src/http/ngx_http_header_filter_module.c
- staticchar ngx_http_server_string[] = "Server: IIS"CRLF #主要是這里
定義了http錯(cuò)誤碼的返回
有時(shí)候我們頁(yè)面程序出現(xiàn)錯(cuò)誤,Nginx會(huì)代我們返回相應(yīng)的錯(cuò)誤代碼,回顯的時(shí)候,會(huì)帶上nginx和版本號(hào),我們把他隱藏起來(lái)
vi src/http/ngx_http_special_response.c
- static u_char ngx_http_error_tail[] =
- "<hr><center>IIS</center>" CRLF
- "</body>" CRLF
- "</html>" CRLF
- ;
利用TCMalloc優(yōu)化Nginx的性能
TCMalloc是谷歌開(kāi)發(fā)的開(kāi)源工具。與標(biāo)準(zhǔn)的glibc庫(kù)的malloc相比,TCMalloc庫(kù)在內(nèi)存分配效率和速度上要高很多,提高了服務(wù)器在高并發(fā)情況下的性能,從而降低了系統(tǒng)的負(fù)載。
需要安裝google-perftools和libunwind(32位系統(tǒng)不需要安裝)兩個(gè)軟件。
安裝libunwind庫(kù)
下載地址http://download.savannah.gnu.org/releases/libunwind/選擇相應(yīng)版本。
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz
CFLAGS=-fPIC ./configure && make CFLAGS=-fPIC make CFLAGS=-fPIC install
安裝google-perftools
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.5/gperftools-2.5.tar.gz
./confighre && make && make install
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig
重新編譯之后為Google-perftools創(chuàng)建一個(gè)線程目錄,在這里將文件放在/tmp/tcmalloc下,并給權(quán)限777
在Nginx的主配置文件中添加

重啟Nginx。
可以查看 lsof -n | grep tcmalloc 查看
Nginx內(nèi)核優(yōu)化參數(shù)
在Nginx內(nèi)核參數(shù)優(yōu)化主要在Linux系統(tǒng)中針對(duì)Nginx應(yīng)用而進(jìn)行的系統(tǒng)內(nèi)核參數(shù)優(yōu)化。僅供參考:
net.ipv4.tcp_max_tw_buckets = 6000
timewait的數(shù)量,默認(rèn)是180000。
net.ipv4.ip_local_port_range = 1024 65000
允許系統(tǒng)打開(kāi)的端口范圍。
net.ipv4.tcp_tw_recycle = 1
啟用timewait快速回收。
net.ipv4.tcp_tw_reuse = 1
開(kāi)啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接。
net.ipv4.tcp_syncookies = 1
開(kāi)啟SYN Cookies,當(dāng)出現(xiàn)SYN等待隊(duì)列溢出時(shí),啟用cookies來(lái)處理。
net.core.somaxconn = 262144
web應(yīng)用中l(wèi)isten函數(shù)的backlog默認(rèn)會(huì)給我們內(nèi)核參數(shù)的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG默認(rèn)為511,所以有必要調(diào)整這個(gè)值。
也可以在nginx配置文件的linsten 80 后面加上這個(gè)backlog參數(shù),但是不能超過(guò)內(nèi)核里面設(shè)定的數(shù)值,如下:
Linsten 80 backlog=65533;
net.core.netdev_max_backlog = 262144
每個(gè)網(wǎng)絡(luò)接口接收數(shù)據(jù)包的速率比內(nèi)核處理這些包的速率快時(shí),允許送到隊(duì)列的數(shù)據(jù)包的最大數(shù)目。
net.ipv4.tcp_max_orphans = 262144
系統(tǒng)中最多有多少個(gè)TCP套接字不被關(guān)聯(lián)到任何一個(gè)用戶(hù)文件句柄上。如果超過(guò)這個(gè)數(shù)字,孤兒連接將即刻被復(fù)位并打印出警告信息。這個(gè)限制僅僅是為了防止簡(jiǎn)單的DoS攻擊,不能過(guò)分依靠它或者人為地減小這個(gè)值,更應(yīng)該增加這個(gè)值(如果增加了內(nèi)存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
記錄的那些尚未收到客戶(hù)端確認(rèn)信息的連接請(qǐng)求的最大值。對(duì)于有128M內(nèi)存的系統(tǒng)而言,缺省值是1024,小內(nèi)存的系統(tǒng)則是128。
net.ipv4.tcp_timestamps = 0
時(shí)間戳可以避免序列號(hào)的卷繞。一個(gè)1Gbps的鏈路肯定會(huì)遇到以前用過(guò)的序列號(hào)。時(shí)間戳能夠讓內(nèi)核接受這種”異常”的數(shù)據(jù)包。這里需要將其關(guān)掉。
net.ipv4.tcp_synack_retries = 1
為了打開(kāi)對(duì)端的連接,內(nèi)核需要發(fā)送一個(gè)SYN并附帶一個(gè)回應(yīng)前面一個(gè)SYN的ACK。也就是所謂三次握手中的第二次握手。這個(gè)設(shè)置決定了內(nèi)核放棄連接之前發(fā)送SYN+ACK包的數(shù)量。
net.ipv4.tcp_syn_retries = 1
在內(nèi)核放棄建立連接之前發(fā)送SYN包的數(shù)量。
net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求關(guān)閉,這個(gè)參數(shù)決定了它保持在FIN-WAIT-2狀態(tài)的時(shí)間。對(duì)端可以出錯(cuò)并永遠(yuǎn)不關(guān)閉連接,甚至意外當(dāng)機(jī)。缺省值是60秒。2.2 內(nèi)核的通常值是180秒,你可以按這個(gè)設(shè)置,但要記住的是,即使你的機(jī)器是一個(gè)輕載的WEB服務(wù)器,也有因?yàn)榇罅康乃捞捉幼侄鴥?nèi)存溢出的風(fēng)險(xiǎn),F(xiàn)IN- WAIT-2的危險(xiǎn)性比FIN-WAIT-1要小,因?yàn)樗疃嘀荒艹缘?.5K內(nèi)存,但是它們的生存期長(zhǎng)些。
net.ipv4.tcp_keepalive_time = 30
當(dāng)keepalive起用的時(shí)候,TCP發(fā)送keepalive消息的頻度。缺省是2小時(shí)。
一個(gè)完整的內(nèi)核優(yōu)化配置
net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_rmem = 4096 87380 4194304 net.ipv4.tcp_wmem = 4096 16384 4194304 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.core.somaxconn = 262144 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_keepalive_time = 30 net.ipv4.ip_local_port_range = 1024 65000
一個(gè)簡(jiǎn)單的nginx優(yōu)化配置文件
user www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000;
error_log /www/log/nginx_error.log crit;
pid /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 204800;
events
{
use epoll;
worker_connections 204800;
}
http
{
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
keys_zone=TEST:10m
inactive=5m;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 16k;
fastcgi_buffers 16 16k;
fastcgi_busy_buffers_size 16k;
fastcgi_temp_file_write_size 16k;
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
tcp_nodelay on;
gzip on;
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;
gzip_vary on;
server
{
listen 80 backlog=65533;
server_name www.linuxyan.com;
index index.php index.htm;
root /www/html/;
location /status
{
stub_status on;
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
}
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
access_log /www/log/access.log access;
}
}
關(guān)于FastCGI的幾個(gè)指令
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
這個(gè)指令為FastCGI緩存指定一個(gè)路徑,目錄結(jié)構(gòu)等級(jí),關(guān)鍵字區(qū)域存儲(chǔ)時(shí)間和非活動(dòng)刪除時(shí)間。
fastcgi_connect_timeout 300;
指定連接到后端FastCGI的超時(shí)時(shí)間。
fastcgi_send_timeout 300;
向FastCGI傳送請(qǐng)求的超時(shí)時(shí)間,這個(gè)值是指已經(jīng)完成兩次握手后向FastCGI傳送請(qǐng)求的超時(shí)時(shí)間。
fastcgi_read_timeout 300;
接收FastCGI應(yīng)答的超時(shí)時(shí)間,這個(gè)值是指已經(jīng)完成兩次握手后接收FastCGI應(yīng)答的超時(shí)時(shí)間。
fastcgi_buffer_size 16k;
指定讀取FastCGI應(yīng)答第一部分需要用多大的緩沖區(qū),這里可以設(shè)置為fastcgi_buffers指令指定的緩沖區(qū)大小,上面的指令指定它將使用1個(gè)16k的緩沖區(qū)去讀取應(yīng)答的第一部分,即應(yīng)答頭,其實(shí)這個(gè)應(yīng)答頭一般情況下都很小(不會(huì)超過(guò)1k),但是你如果在fastcgi_buffers指令中指定了緩沖區(qū)的大小,那么它也會(huì)分配一個(gè)fastcgi_buffers指定的緩沖區(qū)大小去緩存。
fastcgi_buffers 16 16k;
指定本地需要用多少和多大的緩沖區(qū)來(lái)緩沖FastCGI的應(yīng)答,如上所示,如果一個(gè)php腳本所產(chǎn)生的頁(yè)面大小為256k,則會(huì)為其分配16個(gè)16k的緩沖區(qū)來(lái)緩存,如果大于256k,增大于256k的部分會(huì)緩存到fastcgi_temp指定的路徑中,當(dāng)然這對(duì)服務(wù)器負(fù)載來(lái)說(shuō)是不明智的方案,因?yàn)閮?nèi)存中處理數(shù)據(jù)速度要快于硬盤(pán),通常這個(gè)值的設(shè)置應(yīng)該選擇一個(gè)你的站點(diǎn)中的php腳本所產(chǎn)生的頁(yè)面大小的中間值,比如你的站點(diǎn)大部分腳本所產(chǎn)生的頁(yè)面大小為256k就可以把這個(gè)值設(shè)置為16 16k,或者4 64k 或者64 4k,但很顯然,后兩種并不是好的設(shè)置方法,因?yàn)槿绻a(chǎn)生的頁(yè)面只有32k,如果用4 64k它會(huì)分配1個(gè)64k的緩沖區(qū)去緩存,而如果使用64 4k它會(huì)分配8個(gè)4k的緩沖區(qū)去緩存,而如果使用16 16k則它會(huì)分配2個(gè)16k去緩存頁(yè)面,這樣看起來(lái)似乎更加合理。
fastcgi_busy_buffers_size 32k;
這個(gè)指令我也不知道是做什么用,只知道默認(rèn)值是fastcgi_buffers的兩倍。
fastcgi_temp_file_write_size 32k;
在寫(xiě)入fastcgi_temp_path時(shí)將用多大的數(shù)據(jù)塊,默認(rèn)值是fastcgi_buffers的兩倍。
fastcgi_cache TEST
開(kāi)啟FastCGI緩存并且為其制定一個(gè)名稱(chēng)。個(gè)人感覺(jué)開(kāi)啟緩存非常有用,可以有效降低CPU負(fù)載,并且防止502錯(cuò)誤。但是這個(gè)緩存會(huì)引起很多問(wèn)題,因?yàn)樗彺娴氖莿?dòng)態(tài)頁(yè)面。具體使用還需根據(jù)自己的需求。
fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m;
為指定的應(yīng)答代碼指定緩存時(shí)間,如上例中將200,302應(yīng)答緩存一小時(shí),301應(yīng)答緩存1天,其他為1分鐘。
fastcgi_cache_min_uses 1;
緩存在fastcgi_cache_path指令inactive參數(shù)值時(shí)間內(nèi)的最少使用次數(shù),如上例,如果在5分鐘內(nèi)某文件1次也沒(méi)有被使用,那么這個(gè)文件將被移除。
fastcgi_cache_use_stale error timeout invalid_header http_500;
不知道這個(gè)參數(shù)的作用,猜想應(yīng)該是讓nginx知道哪些類(lèi)型的緩存是沒(méi)用的。 以上為nginx中FastCGI相關(guān)參數(shù),另外,F(xiàn)astCGI自身也有一些配置需要進(jìn)行優(yōu)化,如果你使用php-fpm來(lái)管理FastCGI,可以修改配置文件中的以下值:
60
同時(shí)處理的并發(fā)請(qǐng)求數(shù),即它將開(kāi)啟最多60個(gè)子線程來(lái)處理并發(fā)連接。
102400
最多打開(kāi)文件數(shù)。
204800
每個(gè)進(jìn)程在重置之前能夠執(zhí)行的最多請(qǐng)求數(shù)。

浙公網(wǎng)安備 33010602011771號(hào)