nginx+php-fpm性能參數(shù)優(yōu)化(配置文件)
技術(shù)支持服務(wù)電話:15308000360 【7x24提供運(yùn)維服務(wù),解決各類(lèi)系統(tǒng)/軟硬件疑難技術(shù)問(wèn)題】
nginx指令中的優(yōu)化(配置文件)
worker_processes 8;
nginx進(jìn)程數(shù),建議按照cpu數(shù)目來(lái)指定,一般為它的倍數(shù)。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
為每個(gè)進(jìn)程分配cpu,上例中將8個(gè)進(jìn)程分配到8個(gè)cpu,當(dāng)然可以寫(xiě)多個(gè),或者將一個(gè)進(jìn)程分配到多個(gè)cpu。
worker_rlimit_nofile 102400;
這個(gè)指令是指當(dāng)一個(gè)nginx進(jìn)程打開(kāi)的最多文件描述符數(shù)目,理論值應(yīng)該是最多打開(kāi)文件數(shù)(ulimit -n)與nginx進(jìn)程數(shù)相除,但是nginx分配請(qǐng)求并不是那么均勻,所以最好與ulimit -n的值保持一致。
use epoll;
使用epoll的I/O模型,這個(gè)不用說(shuō)了吧。
worker_connections 102400;
每個(gè)進(jìn)程允許的最多連接數(shù),理論上每臺(tái)nginx服務(wù)器的最大連接數(shù)為worker_processes*worker_connections。
keepalive_timeout 60;
keepalive超時(shí)時(shí)間。
client_header_buffer_size 4k;
客戶端請(qǐng)求頭部的緩沖區(qū)大小,這個(gè)可以根據(jù)你的系統(tǒng)分頁(yè)大小來(lái)設(shè)置,一般一個(gè)請(qǐng)求的頭部大小不會(huì)超過(guò)1k,不過(guò)由于一般系統(tǒng)分頁(yè)都要大于1k,所以這里設(shè)置為分頁(yè)大小。分頁(yè)大小可以用命令getconf PAGESIZE取得。
open_file_cache max=102400 inactive=20s;
這個(gè)將為打開(kāi)文件指定緩存,默認(rèn)是沒(méi)有啟用的,max指定緩存數(shù)量,建議和打開(kāi)文件數(shù)一致,inactive是指經(jīng)過(guò)多長(zhǎng)時(shí)間文件沒(méi)被請(qǐng)求后刪除緩存。
open_file_cache_valid 30s;
這個(gè)是指多長(zhǎng)時(shí)間檢查一次緩存的有效信息。
open_file_cache_min_uses 1;
open_file_cache指令中的inactive參數(shù)時(shí)間內(nèi)文件的最少使用次數(shù),如果超過(guò)這個(gè)數(shù)字,文件描述符一直是在緩存中打開(kāi)的,如上例,如果有一個(gè)文件在inactive時(shí)間內(nèi)一次沒(méi)被使用,它將被移除。
內(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è)值。
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è)用戶文件句柄上。如果超過(guò)這個(gè)數(shù)字,孤兒連接將即刻被復(fù)位并打印出警告信息。這個(gè)限制僅僅是為了防止簡(jiǎn)單的DoS攻擊,不能過(guò)分依靠它或者人為地減小這個(gè)值,更應(yīng)該增加這個(gè)值(如果增加了內(nèi)存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
記錄的那些尚未收到客戶端確認(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 8080;
server_name ad.test.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è)名稱。個(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;
PHP-FPM是一個(gè)PHPFastCGI進(jìn)程管理器,是只用于PHP的。
PHP-FPM其實(shí)是PHP源代碼的一個(gè)補(bǔ)丁,旨在將FastCGI進(jìn)程管理整合進(jìn)PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP后才可以使用。
現(xiàn)在我們可以在最新的PHP 5.3.2的源碼樹(shù)里下載得到直接整合了PHP-FPM的分支,據(jù)說(shuō)下個(gè)版本會(huì)融合進(jìn)PHP的主分支去。相對(duì)Spawn-FCGI,PHP-FPM在CPU和內(nèi)存方面的控制都更勝一籌,而且前者很容易崩潰,必須用crontab進(jìn)行監(jiān)控,而PHP-FPM則沒(méi)有這種煩惱。
PHP5.3.3已經(jīng)集成php-fpm了,不再是第三方的包了。PHP-FPM提供了更好的PHP進(jìn)程管理方式,可以有效控制內(nèi)存和進(jìn)程、可以平滑重載PHP配置,比spawn-fcgi具有更多優(yōu)點(diǎn),所以被PHP官方收錄了。 在./configure的時(shí)候帶 –enable-fpm參數(shù)即可開(kāi)啟PHP-FPM。
使用PHP-FPM來(lái)控制PHP-CGI的FastCGI進(jìn)程
/usr/local/php/sbin/php-fpm{start|stop|quit|restart|reload|logrotate}
--start 啟動(dòng)php的fastcgi進(jìn)程
--stop 強(qiáng)制終止php的fastcgi進(jìn)程
--quit 平滑終止php的fastcgi進(jìn)程
--restart 重啟php的fastcgi進(jìn)程
--reload 重新平滑加載php的php.ini
--logrotate 重新啟用log文件
php-fpm有兩種執(zhí)行方式, 與Apache一樣,他的進(jìn)程數(shù)也是可以根據(jù)設(shè)置分為動(dòng)態(tài)和靜態(tài)的,一種是直接開(kāi)啟指定數(shù)量的php-fpm進(jìn)程,不再增加或者減少;另一種則是開(kāi)始的時(shí)候開(kāi)啟一定數(shù)量的php-fpm進(jìn)程,當(dāng)請(qǐng)求量變大的時(shí)候,動(dòng)態(tài)的增加php-fpm進(jìn)程數(shù)到上限,當(dāng)空閑的時(shí)候自動(dòng)釋放空閑的進(jìn)程數(shù)到一個(gè)下限。
這兩種不同的執(zhí)行方式,可以根據(jù)服務(wù)器的實(shí)際需求來(lái)進(jìn)行調(diào)整。
這里先說(shuō)一下涉及到這個(gè)的幾個(gè)參數(shù)吧,他們分別是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。
pm表示使用那種方式,有兩個(gè)值可以選擇,就是static(靜態(tài))或者dynamic(動(dòng)態(tài))。在更老一些的版本中,dynamic被稱作apache-like。這個(gè)要注意看配置文件給出的說(shuō)明了。
下面4個(gè)參數(shù)的意思分別為:
pm.max_children:靜態(tài)方式下開(kāi)啟的php-fpm進(jìn)程數(shù)量。
pm.start_servers:動(dòng)態(tài)方式下的起始php-fpm進(jìn)程數(shù)量。
pm.min_spare_servers:動(dòng)態(tài)方式下的最小php-fpm進(jìn)程數(shù)量。
pm.max_spare_servers:動(dòng)態(tài)方式下的最大php-fpm進(jìn)程數(shù)量。
如果dm設(shè)置為static,那么只有pm.max_children這個(gè)參數(shù)生效。系統(tǒng)會(huì)開(kāi)啟設(shè)置的數(shù)個(gè)php-fpm進(jìn)程。
如果dm設(shè)置為dynamic,那么pm.max_children參數(shù)失效,后面3個(gè)參數(shù)生效。系統(tǒng)會(huì)在php-fpm運(yùn)行開(kāi)始的時(shí)候啟動(dòng) pm.start_servers個(gè)php-fpm進(jìn)程,然后根據(jù)系統(tǒng)的需求動(dòng)態(tài)在pm.min_spare_servers和 pm.max_spare_servers之間調(diào)整php-fpm進(jìn)程數(shù)。
那么,對(duì)于我們的服務(wù)器,選擇哪種執(zhí)行方式比較好呢?事實(shí)上,跟Apache一樣,我們運(yùn)行的PHP程序在執(zhí)行完成后,或多或少會(huì)有內(nèi)存泄露的問(wèn) 題。這也是為什么開(kāi)始的時(shí)候一個(gè)php-fpm進(jìn)程只占用3M左右內(nèi)存,運(yùn)行一段時(shí)間后就會(huì)上升到20-30M的原因了。所以,動(dòng)態(tài)方式因?yàn)闀?huì)結(jié)束掉多余 的進(jìn)程,可以回收釋放一些內(nèi)存,所以推薦在內(nèi)存較少的服務(wù)器或者VPS上使用。具體最大數(shù)量根據(jù) 內(nèi)存/20M 得到。比如說(shuō)512M的VPS,建議pm.max_spare_servers設(shè)置為20。至于pm.min_spare_servers,則建議根據(jù)服 務(wù)器的負(fù)載情況來(lái)設(shè)置,比較合適的值在5~10之間。
然后對(duì)于比較大內(nèi)存的服務(wù)器來(lái)說(shuō),設(shè)置為靜態(tài)的話會(huì)提高效率。因?yàn)轭l繁開(kāi)關(guān)php-fpm進(jìn)程也會(huì)有時(shí)滯,所以內(nèi)存夠大的情況下開(kāi)靜態(tài)效果會(huì)更好。數(shù)量也可以根據(jù) 內(nèi)存/30M 得到。比如說(shuō)2GB內(nèi)存的服務(wù)器,可以設(shè)置為50;4GB內(nèi)存可以設(shè)置為100等。
DEMO參數(shù)如下:
pm=dynamic
pm.max_children=20
pm.start_servers=5
pm.min_spare_servers=5
pm.max_spare_servers=20
這樣就可以最大的節(jié)省內(nèi)存并提高執(zhí)行效率。
我本機(jī)配置文件如下
服務(wù)器配置
CPU:24核
內(nèi)存:32G
硬盤(pán):RAID5 SAS146G 15000轉(zhuǎn)硬盤(pán)陣列
提示硬件配置沒(méi)這么高不要設(shè)這么多!
# nginx conf conf/nginx.conf
# Last Updated 2010.06.01
user www www;
worker_processes 48;
error_log logs/error.log notice;
pid logs/nginx.pid;
worker_rlimit_nofile 409600;
events {
use epoll;
worker_connections 409600;
}
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
limit_conn_zone $binary_remote_addr zone=one:32k;
###########xinjiade###########################
fastcgi_cache_path /www/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=102400 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 1;
##############################################
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
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;
log_format wwwlogs '$remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
#include default.conf;
include vhost/*.conf;
}
php-fmp 設(shè)置
pm.max_children=512
pm.start_servers=128
pm.min_spare_servers=30
pm.max_spare_servers=128