LNMP架構中PHP是運行在FastCGI模式下,按照官方的說法,php-cgi會在每一個請求結束的時候會回收腳本使用的所有內存,可是並不會釋放給操做系統,而是繼續持有以應對下一次PHP請求。而php-fpm是FastCGI進程管理器,用於控制php的內存和進程等。php
php-fpm.conf幾個重要的參數說明以下:nginx
pm = dynamic 服務器
#指定進程管理方式,有3種可供選擇:static、dynamic和ondemand。若是選擇static,則由pm.max_children指定固定的子進程數。若是選擇dynamic,則由pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers 參數決定架構
pm.max_children = 16 socket
#static模式下建立的子進程數或dynamic模式下同一時刻容許最大的php-fpm子進程數量tcp
pm.start_servers = 10 #動態方式下的起始php-fpm進程數量。默認值爲:min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.min_spare_servers = 8 #動態方式下服務器空閒時最小php-fpm進程數量,若是小於此值,會建立新的進程。
pm.max_spare_servers = 16 #動態方式下服務器空閒時最大php-fpm進程數量,若是大於此值,會kill部分進程php-fpm
pm.max_requests = 2000 測試
#每一個進程處理多少個請求以後自動終止,能夠有效防止內存溢出,若是爲0則不會自動終止,默認爲0spa
#設置每一個子進程重生以前服務的請求數. 對於可能存在內存泄漏的第三方模塊來講是很是有用的. 若是設置爲 '0' 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變量. 默認值: 0操作系統
pm.process_idle_timeout = 10s
#空閒多少秒以後進程會被kill,默認爲10s
request_terminate_timeout = 120
#設置單個請求的超時停止時間. 該選項可能會對php.ini設置中的'max_execution_time'由於某些特殊緣由沒有停止運行的腳本有用. 設置爲 '0' 表示 'Off'.當常常出現502錯誤時能夠嘗試更改此選項。
pm.status_path = /status
必定要添加到 php-fpm.conf 文件中的最後,不然重啓php-fpm時會出現錯誤
註冊的URI,以展現php-fpm狀態的統計信息,其中統計頁面的信息有:
pool – fpm池子名稱,大多數爲www
process manager – 進程管理方式,值:static, dynamic or ondemand. dynamic
start time – 啓動日期,若是reload了php-fpm,時間會更新
start since – 運行時長
accepted conn – 當前池子接受的請求數
listen queue – 請求等待隊列,若是這個值不爲0,那麼要增長FPM的進程數量
max listen queue – 請求等待隊列最高的數量
listen queue len – socket等待隊列長度
idle processes – 空閒進程數量
active processes – 活躍進程數量
total processes – 總進程數量
max active processes – 最大的活躍進程數量(FPM啓動開始算)
max children reached - 進程最大數量限制的次數,若是這個數量不爲0,那說明你的最大進程數量過小了,請改大一點。
slow requests – 啓用了php-fpm slow-log,緩慢請求的數量
FULL格式顯示項:
pid – 進程PID,能夠單獨kill這個進程.
state – 當前進程的狀態 (Idle, Running, …)
start time – 進程啓動的日期
start since – 當前進程運行時長
requests – 當前進程處理了多少個請求
request duration – 請求時長(微妙)
request method – 請求方法 (GET, POST, …)
request URI – 請求URI
content length – 請求內容長度 (僅用於 POST)
user – 用戶 (PHP_AUTH_USER) (or ‘-’ 若是沒設置)
script – PHP腳本 (or ‘-’ if not set)
last request cpu – 最後一個請求CPU使用率。
last request memorythe - 上一個請求使用的內存
NGINX配置
server { listen 80; server_name 127.0.0.1; location /nginx_status { stub_status on; access_log off; } location /phpfpm_status { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; } }
ping.path = /ping
能夠用來測試php-fpm是否存活並能夠響應
pid = run/php-fpm.pid
#pid設置,默認在安裝目錄中的var/run/php-fpm.pid,建議開啓
error_log = log/php-fpm.log
#錯誤日誌,默認在安裝目錄中的var/log/php-fpm.log
log_level = notice
#錯誤級別. 可用級別爲: alert(必須當即處理), error(錯誤狀況), warning(警告狀況), notice(通常重要信息), debug(調試信息). 默認: notice.
daemonize = yes
#後臺執行fpm,默認值爲yes,若是爲了調試能夠改成no。在FPM中,可使用不一樣的設置來運行多個進程池。 這些設置能夠針對每一個進程池單獨設置。
listen = 127.0.0.1:9000
#fpm監聽端口,即nginx中php處理的地址,通常默認值便可。可用格式爲: 'ip:port', 'port', '/path/to/unix/socket'. 每一個進程池都須要設置。
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket設置選項,若是使用tcp方式訪問,這裏註釋便可
user = www
group = www
listen.allowed_clients = 127.0.0.1
#容許訪問FastCGI進程的IP,設置any爲不限制IP,若是要設置其餘主機的nginx也能訪問這臺FPM進程,listen處要設置成本地可被訪問的IP。默認值是any。每一個地址是用逗號分隔. 若是沒有設置或者爲空,則容許任何服務器請求鏈接
request_slowlog_timeout = 10s
停止運行的腳本有用. 設置爲 '0' 表示 'Off'.當常常出現502錯誤時能夠嘗試更改此選項。
slowlog = log/$pool.log.slow
#慢請求的記錄日誌,配合request_slowlog_timeout使用
pm三種進程管理模式說明以下:
pm = static,始終保持一個固定數量的子進程,這個數由pm.max_children定義,這種方式很不靈活,也一般不是默認的。
pm = dynamic,啓動時會產生固定數量的子進程(由pm.start_servers控制)能夠理解成最小子進程數,而最大子進程數則由pm.max_children去控制,子進程數會在最大和最小數範圍中變化。閒置的子進程數還能夠由另2個配置控制,分別是pm.min_spare_servers和pm.max_spare_servers。若是閒置的子進程超出了pm.max_spare_servers,則會被殺掉。小於pm.min_spare_servers則會啓動進程(注意,pm.max_spare_servers應小於pm.max_children)。
pm = ondemand,這種模式和pm = dynamic相反,把內存放在第一位,每一個閒置進程在持續閒置了pm.process_idle_timeout秒後就會被殺掉,若是服務器長時間沒有請求,就只會有一個php-fpm主進程。弊端是遇到高峯期或者若是pm.process_idle_timeout的值過短的話,容易出現504 Gateway Time-out錯誤,所以pm = dynamic和pm = ondemand誰更適合視實際狀況而定。
實際使用過程當中發現php-fpm進程還存長期佔用內存而不釋放的問題。解決的方法就是減小pm.max_requests數。最大請求數max_requests,即當一個 PHP-CGI 進程處理的請求數累積到 max_requests 個後,自動重啓該進程,這樣達到了釋放內存的目的了。
pm.max_requests = 500
當php-fpm進程達到了pm.max_requests設定的數值後,就會重啓該進程,從而釋放內存。下圖是我測試後的效果,能夠看出php-fpm進程被強制結束並釋放了內存。