php-fpm配置解說(PHP-FPM參數(shù)優(yōu)調(diào))
[重要通告]如您遇疑難雜癥,本站支持知識付費業(yè)務(wù),掃右邊二維碼加博主微信,可節(jié)省您寶貴時間哦!
最近處理一些PHP腳本的時候,要經(jīng)常用到php-fpm,這個東西真是費腦殼,但也沒有啥好的辦法,該用還得用,不然也沒有其他啥好的辦法來替代品!
php-fpm解說
php-fpm全名是PHP FastCGI進(jìn)程管理器
php-fpm啟動后會先讀php.ini,然后再讀相應(yīng)的conf配置文件,conf配置可以覆蓋php.ini的配置。
啟動php-fpm之后,會創(chuàng)建一個master進(jìn)程,監(jiān)聽9000端口(可配置),master進(jìn)程又會根據(jù)fpm.conf/www.conf去創(chuàng)建若干子進(jìn)程,子進(jìn)程用于處理實際的業(yè)務(wù)。
當(dāng)有客戶端(比如nginx)來連接9000端口時,空閑子進(jìn)程會自己去accept,如果子進(jìn)程全部處于忙碌狀態(tài),新進(jìn)的待accept的連接會被master放進(jìn)隊列里,等待fpm子進(jìn)程空閑;
這個存放待accept的半連接的隊列有多長,由 listen.backlog 配置。
php-fpm配置與參數(shù)優(yōu)調(diào)
配置文件位置一般在PHP目錄下的etc/php-fpm.d/*.conf
pm.max_children = 100
最大子進(jìn)程數(shù)量,越多越好,一般每個php-cgi所耗費的內(nèi)存為20M左右
如果最大數(shù)量設(shè)置為100,則在峰值的時候php-cgi所耗內(nèi)存在2000M以內(nèi)
如果這個值設(shè)置的比較小,那么等待的請求時間會出現(xiàn)502超時
4G內(nèi)存服務(wù)器可以設(shè)置成200
pm.start_servers = 20
pm.start_servers:啟動時創(chuàng)建的子進(jìn)程數(shù),10~20之間就可以,20個的話是400M內(nèi)存
pm.max_requests = 10240
為避免內(nèi)存泄露,php-fpm有這么一個機制,當(dāng)一個php-cgi進(jìn)程處理的請求數(shù)達(dá)到這個配置后,則會自動重啟該進(jìn)程
所以在高并發(fā)中,經(jīng)常導(dǎo)致502錯誤
解決方法就是把這個值設(shè)置大一些,減少進(jìn)程重啟次數(shù),減少高并發(fā)情況下502錯誤。
request_terminate_timeout = 400
單個請求的超時中止時間,超時后會終止進(jìn)程,nginx發(fā)現(xiàn)信號斷了,就會給客戶端返回502錯誤。
和php.ini的max_execution_time配置不沖突,誰先達(dá)到時間誰先起作用。
由于程序中有請求第三方接口等待,所以建議這個值設(shè)置為400秒,長一點不會出現(xiàn)502錯誤
pm.min_spare_servers = 10
保證空閑進(jìn)程數(shù)最小值,如果空閑進(jìn)程小于此值,則創(chuàng)建新的子進(jìn)程
pm.max_spare_servers = 30
保證空閑進(jìn)程數(shù)最大值,如果空閑進(jìn)程大于此值,此進(jìn)行清理
rlimit_files = xxx
設(shè)置文件打開描述符的rlimit限制,可使用 ulimit -n 查看
其他:pm.status_path = /status
可以用來查看php-fpm運行情況,配置打開后再在nginx進(jìn)行代理轉(zhuǎn)發(fā),就可以在瀏覽器訪問了
/status顯示的參數(shù)意義:
pool – fpm池子名稱,大多數(shù)為www
process manager – 進(jìn)程管理方式,值:static, dynamic or ondemand. dynamic
start time – 啟動日期,如果reload了php-fpm,時間會更新
start since – 運行時長
accepted conn – 當(dāng)前池子接受的請求數(shù)
listen queue – 請求等待隊列,如果這個值不為0,那么要增加FPM的進(jìn)程數(shù)量
max listen queue – 請求等待隊列最高的數(shù)量
listen queue len – socket等待隊列長度
idle processes – 空閑進(jìn)程數(shù)量
active processes – 活躍進(jìn)程數(shù)量
total processes – 總進(jìn)程數(shù)量
max active processes – 最大的活躍進(jìn)程數(shù)量(FPM啟動開始算)
max children reached - 進(jìn)程最大數(shù)量限制的次數(shù),如果這個數(shù)量不為0,那說明你的最大進(jìn)程數(shù)量太小了,請改大一點。
slow requests – 啟用了php-fpm slow-log,緩慢請求的數(shù)量
還可以在訪問時,在網(wǎng)址后面追加?full,可以查看更詳細(xì)的狀態(tài),參數(shù)值有:
pid – 進(jìn)程PID,可以單獨kill這個進(jìn)程.
state – 當(dāng)前進(jìn)程的狀態(tài) (Idle, Running, …)
start time – 進(jìn)程啟動的日期
start since – 當(dāng)前進(jìn)程運行時長
requests – 當(dāng)前進(jìn)程處理了多少個請求
request duration – 請求時長(微妙)
request method – 請求方法 (GET, POST, …)
request URI – 請求URI
content length – 請求內(nèi)容長度 (僅用于 POST)
user – 用戶 (PHP_AUTH_USER) (or ‘-’ 如果沒設(shè)置)
script – PHP腳本 (or ‘-’ if not set)
last request cpu – 最后一個請求CPU使用率。
last request memorythe - 上一個請求使用的內(nèi)存
nginx轉(zhuǎn)發(fā)配置:
location /status { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; }
其他:ping.path = /ping
用于外部檢測FPM是否存活并且可以響應(yīng)請求
nginx轉(zhuǎn)發(fā)配置:
location /ping { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; }
注:macOS系統(tǒng)對進(jìn)程數(shù)、打開文件數(shù)等等有限制,為了方便操作,直接在Linux下測試。
修改配置后重載配置文件:
ps aux|grep php-fpm 得到Ss類型運行的pid
kill -USR2 pid
php7以上版本的php-fpm參數(shù)配置
php-fpm的核心參數(shù)配置,默認(rèn)如下:
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
只針對動態(tài)方式dynamic說明如下:
max_children:動態(tài)方式下限定php-fpm的最大進(jìn)程數(shù)
start_servers:動態(tài)方式下的起始php-fpm進(jìn)程數(shù)量
min_spare_servers :動態(tài)方式空閑狀態(tài)下的最小php-fpm進(jìn)程數(shù)量
max_spare_servers :動態(tài)方式空閑狀態(tài)下的最大php-fpm進(jìn)程數(shù)量
這些參數(shù)如果注意改錯了參數(shù)會導(dǎo)致php-fpm啟動不了,nginx也就無法訪問php文件,可查看日志排查錯誤:
/usr/local/php/var/log/php-fpm.log
規(guī)則匯總:
1.max_children 必須大于 min_spare_servers
2.max_children 必須大于 max_spare_servers
3.start_servers 必須大于 min_spare_servers
4.start_servers = min_spare_servers + (max_spare_servers - min_spare_servers) /
php-fpm全局配置說明(PHP5.6載入)
配置里面的所有相對路徑,都是相對于php的安裝路徑。
除了有php-fpm.conf配置文件外,通常還有其他的*.conf配置文件(也可以不要,直接在php-fpm.conf配置)用于配置進(jìn)程池,不同的進(jìn)程池可以用不同的用戶執(zhí)行,監(jiān)聽不同的端口,處理不同的任務(wù);多個進(jìn)程池共用一個全局配置。
[www] #進(jìn)程池的名字; user = www group = www #以什么用戶什么組的權(quán)限來運行[www]這個進(jìn)程池,用戶,必須要設(shè)置,用戶組,如果沒有設(shè)置,則默認(rèn)用戶的組被使用; listen.backlog = 65535 #子進(jìn)程未accept處理的客戶端請求隊列大小,-1 on FreeBSD and OpenBSD,其他平臺默認(rèn)65535,高并發(fā)時重要,合理設(shè)置會及時處理排隊的請求;太大會積壓太多,處理完后nginx在前面都等超時斷開這個和fpm的socket連接了,就杯具了。不要用-1,建議1024以上,最好是2的冪值(注意:不同版本的默認(rèn)值是不同的,php5多是128,php7多是511)。 #1:一個池共用一個backlog隊列,所有的池進(jìn)程都去這個隊列里accept連接; #2:最大數(shù)量受限于系統(tǒng)配置cat /proc/sys/net/core/somaxconn,系統(tǒng)配置修改:vim /etc/sysctl.conf,增加net.core.somaxconn =1024則最大為1024,然后php最大的backlog可以到1024。 listen = 127.0.0.1:9000 #進(jìn)程池[www]的監(jiān)聽端口,可用格式為:'ip:port','port','/path/to/unix/socket'。每個進(jìn)程池都需要設(shè)置。如果nginx和php在不同的機器上,只能用機器真實ip+端口的格式,如果在同一臺機器上,還可以選擇unix soxket方式,這種理論上速度會提升31%,但高并發(fā)下不夠穩(wěn)定。 listen.owner = www listen.group = www listen.mode = 0666 #unix socket設(shè)置選項,如果使用tcp方式訪問,這里注釋即可。 listen.acl_users = www,php #當(dāng)系統(tǒng)支持 POSIX ACL(Access Control Lists)時,可以設(shè)置使用此選項。 當(dāng)設(shè)置了的時候,將會忽略 listen.owner 和 listen.group。值是逗號分割的用戶名列表。 PHP 5.6.5 起可用。 listen.acl_groups=web #參見 listen.acl_users。 值是逗號分割的用戶組名稱列表。 PHP 5.6.5 起可用。 listen.allowed_clients = 127.0.0.1 #允許訪問FastCGI進(jìn)程的IP白名單,設(shè)置any為不限制IP,如果要設(shè)置其他主機的nginx也能訪問這臺FPM進(jìn)程,listen處要設(shè)置成本地可被訪問的IP。每個地址是用逗號分隔。如果沒有設(shè)置或者為空,則允許任何服務(wù)器請求連接。 process.priority = -19 #該池進(jìn)程的權(quán)限,同樣要master進(jìn)程是root用戶才有效,和全局那個一樣,不設(shè)置的話會繼承master進(jìn)程的優(yōu)先級。 pm = dynamic #可選static,dynamic,ondemand,也就是說php-fpm有三種進(jìn)程管理模式,默認(rèn)dynamic。 #1:static,固定啟動若干(即pm.max_children)php進(jìn)程,保持不變。 #有效配置:pm.max_children #2:ondemand,這種模式剛啟動時不會啟動任何php進(jìn)程,只有php-fpm接收到請求時才會根據(jù)需求啟動php進(jìn)程,最大為pm.max_children個,另外若php進(jìn)程空閑時間達(dá)到pm.process_idle_timeout(單位s),就會kill掉該進(jìn)程。 #有效配置:pm.max_children,pm.process_idle_timeout #3:dynamic,這種是最常用的,根據(jù)相關(guān)配置動態(tài)調(diào)整php進(jìn)程個數(shù); #有效配置如下: #pm.max_children : 最大php進(jìn)程數(shù); #pm.min_spare_servers:最小的空閑php進(jìn)程數(shù),少與該值會啟動php進(jìn)程(這里的空閑并不是指完全空閑的php進(jìn)程,可以直接理解為啟動的php進(jìn)程就好了,把空閑二字去掉更貼切); #pm.max_spare_servers:最大的空閑php進(jìn)程數(shù),多余的會被kill; #pm.start_servers : php-fpm啟動時的php進(jìn)程數(shù),它的值需要在min_spare_servers和max_spare_servers之間,默認(rèn)值:min_spare_servers(max_spare_servers - min_spare_servers) / 2; #pm.max_requests ,默認(rèn)為0(此時等于PHP_FCGI_MAX_REQUESTS)。為了便于描述,此處假設(shè)它的值是500,那么這個參數(shù)的作用是一個php進(jìn)程(即fpm的一個子進(jìn)程)處理500個請求后會被kill,然后再啟動一個php進(jìn)程,這樣可以防止因為內(nèi)存泄漏導(dǎo)致的php進(jìn)程占用內(nèi)存過高的問題。 access.log = var/log/php-fpm/$pool-access.log #訪問文件日志; access.format = "%R - %u %t “%m %r%Q%q” %s %f %{mili}d %{kilo}M %C%%" #設(shè)定訪問日志的格式。 slowlog = /var/log/php-fpm/$pool-slow.log #慢請求日志; request_slowlog_timeout #默認(rèn)為0(不啟用),此處假設(shè)它的值是10,則超過10s未響應(yīng)的請求就是慢請求,會被記錄到慢請求日志中; request_terminate_timeout #默認(rèn)為0(不啟用),此處假設(shè)它的值是20,則若某個請求超過20s未響應(yīng),相應(yīng)的php進(jìn)程會被kill掉,和php.ini中的max_execution_time效果類似。 php_value ,php_flag, php_admin_value , php_admin_flag #設(shè)置php.ini中的配置,后二者相比前兩者,不能被 PHP 代碼中的 ini_set() 及相似函數(shù)覆蓋。 #最重要的就是pm相關(guān)的幾個配置了,還有一些配置采用默認(rèn)就好,詳情見官網(wǎng)。 【全局配置】 pid = run/php-fpm.pid #pid設(shè)置。 error_log = log/php-fpm.log #錯誤日志。 log_level = notice #錯誤級別。上面的php-fpm.log紀(jì)錄的錯誤等級??捎眉墑e為:alert(必須立即處理),error(錯誤情況),warning(警告情況),notice(一般重要信息),debug(調(diào)試信息)。默認(rèn):notice。 syslog.facility = daemon #把日志寫進(jìn)系統(tǒng)log,linux還不夠熟悉,暫時不用理會。 syslog.ident = php-fpm #系統(tǒng)日志標(biāo)示(前綴),如果跑了多個fpm進(jìn)程池,需要用這個來區(qū)分日志是誰的。 emergency_restart_threshold = 5 emergency_restart_interval = 60 #表示在60s內(nèi)出現(xiàn)SIGSEGV或者SIGBUS錯誤的php-cgi進(jìn)程數(shù)如果超過 emergency_restart_threshold個,php-fpm就會優(yōu)雅重啟。這兩個選項一般保持默認(rèn)值。0 表示‘關(guān)閉該功能’。默認(rèn)值: 0 (關(guān)閉)。 process_control_timeout = 0 #設(shè)置子進(jìn)程接受主進(jìn)程復(fù)用信號的超時時間??捎脝挝唬簊(秒),m(分),h(小時),或者 d(天) 默認(rèn)單位: s(秒)。默認(rèn)值: 0。 process.max = 128 #當(dāng)動態(tài)管理子進(jìn)程時,fpm最多能fork多少個進(jìn)程,默認(rèn)0表示無限制,這是所有進(jìn)程池能啟動子進(jìn)程的總和,謹(jǐn)慎使用。 process.priority = -19 #設(shè)置子進(jìn)程的優(yōu)先級,在master進(jìn)程以root用戶啟動時有效;如果沒有設(shè)置,子進(jìn)程會繼承master進(jìn)程的優(yōu)先級,值范圍-19(最高)到20(最低),默認(rèn)不設(shè)置。 rlimit_files = 1024 #設(shè)置master進(jìn)程最多能打開的文件,默認(rèn)為系統(tǒng)的值。 rlimit_core = 0 #master進(jìn)程核心rlimit限制值;可選unlimited或>=0的整數(shù),默認(rèn)為系統(tǒng)的值。 events.mechanism = epoll #事件處理機制,默認(rèn)自動檢測,可選值:select(any POSIX os), poll(any POSIX os), epoll(linux>=2.5.44), kqueue(FreeBSD >= 4.1,OpenBSD >= 2.9, NetBSD >= 2.0), /dev/poll(Solaris >= 7),port(Solaris >= 10)。linux>=2.5.44會默認(rèn)epoll,效果最好的IO方式。 systemd_interval = 10s #當(dāng)fpm被設(shè)置為系統(tǒng)服務(wù)時,多久向服務(wù)器報告一次狀態(tài),單位有s,m,h。 daemonize = yes #作為守護(hù)進(jìn)程運行php-fpm。默認(rèn)值為yes。
問題未解決?付費解決問題加Q或微信 2589053300 (即Q號又微信號)右上方掃一掃可加博主微信
所寫所說,是心之所感,思之所悟,行之所得;文當(dāng)無敷衍,落筆求簡潔。 以所舍,求所獲;有所依,方所成!