PHP-FPM 不徹底指南

fpm工做流程

fpm全名是FastCGI進程管理器(FastCGI是啥?瞭解下cgi和fastcgi)。php

fpm啓動後會先讀php.ini,而後再讀相應的conf配置文件,conf配置能夠覆蓋php.ini的配置。啓動fpm以後,會建立一個master進程,監聽9000端口(可配置),master進程又會根據fpm.conf/www.conf去建立若干子進程,子進程用於處理實際的業務。當有客戶端(好比nginx)來鏈接9000端口時,空閒子進程會本身去accept,若是子進程所有處於忙碌狀態,新進的待accept的鏈接會被master放進隊列裏,等待fpm子進程空閒;這個存放待accept的半鏈接的隊列有多長,由 listen.backlog 配置。html

fpm配置說明

配置裏面的全部相對路徑,都是相對於php的安裝路徑。linux

進程池

除了有php-fpm.conf配置文件外,一般還有其餘的*.conf配置文件(也能夠不要,直接在php-fpm.conf配置)用於配置進程池,不一樣的進程池能夠用不一樣的用戶執行,監聽不一樣的端口,處理不一樣的任務;多個進程池共用一個全局配置。nginx

include=/opt/remi/php56/root/etc/php-fpm.d/*.conf 載入其餘的配置文件。git

全局配置:

1.0 pid = /opt/remi/php56/root/var/run/php-fpm/php-fpm.pid pid進程文件,默認爲none。web

2.0 error_log = /opt/remi/php56/root/var/log/php-fpm/error.log 錯誤日誌位置,默認:安裝路徑 #INSTALL_PREFIX#/log/php-fpm.log。若是設置爲syslog,log就會發送給syslogd服務而不會寫進文件裏。apache

3.0 syslog.facility = daemon 把日誌寫進系統log,linux還不夠熟悉,暫時不用理會。json

3.1 syslog.ident = php-fpm 系統日誌標示,若是跑了多個fpm進程,須要用這個來區分日誌是誰的。vim

4.0 log_level = notice 日誌等級,默認notice,可選:alert, error, warning, notice, debug瀏覽器

5.0 emergency_restart_threshold = 60 配合5.1用

5.1 emergency_restart_interval = 60s 若是在此參數設置的時間內,出現SIGSEGV或SIGBUS的子進程數超過5.0號參數設置的值,那麼fpm就會優雅的重啓,值是0表示off這個功能,可用的單位有:s秒,m分,h時,d天。

6.0 process_control_timeout = 0 設置子進程接受主進程複用信號的超時時間。這個天天明白,是過了這個時間就不能複用了?

7.0 process.max = 128 當動態管理子進程時,fpm最多能fork多少個進程,0表示無限制,這是全部進程池能啓動子進程的總和,謹慎使用。

8.0 process.priority = -19 設置子進程的優先級,在master進程以root用戶啓動時有效;若是沒有設置,子進程會繼承master進程的優先級,值範圍-19(最高)到20(最低),默認不設置。

9.0 daemonize = yes 設置成no用於調試bug,默認爲yes。

10.0 rlimit_files = 1024 設置master進程最多能打開的文件,默認爲系統的值。

11.0 rlimit_core = 0 master進程核心rlimit限制值;可選unlimited或>=0的整數,默認爲系統的值。

12.0 events.mechanism = epoll 事件處理機制,默認自動檢測,可選值:select,poll,epoll(linux>=2.5.44),kqueue,/dev/poll,port

13.0 systemd_interval = 10s 當fpm被設置爲系統服務時,多久向服務器報告一次狀態,單位有s,m,h。

進程池配置 pool Definitions:

在不一樣的監聽端口和不一樣的管理選項下能夠跑任意數量的池,並無個數限制;

池的名字用於 logs 和 stats。

1.0 user = apache,group = apache 以什麼用戶什麼組的權限來運行池fpm。

用apache能夠像httpd服務同樣去訪問某些目錄

2.0 listen = 127.0.0.1:9000 監聽的ip和端口,能夠 /path/to/unix/socket 來監聽unix socket,性能更好。

3.0 listen.backlog = 65535 未accept處理的socket隊列大小,-1 on FreeBSD and OpenBSD,其餘平臺默認65535,高併發時重要,合理設置會及時處理排隊的請求;太大會積壓太多,處理完後nginx在前面都等超時斷開這個和fpm的socket鏈接了,就杯具了。不要用-1,建議1024以上,最好是2的冪值。

  • 一個池共用一個backlog隊列,全部的池進程都去這個隊列裏accept鏈接。
  • 最大數量受限於系統配置 cat /proc/sys/net/core/somaxconn,系統配置修改:vim /etc/sysctl.conf,增長 net.core.somaxconn = 2000 則最大爲2000,而後php最大的backlog能夠到2000。

4.0 用socket鏈接方式時,指定擁有unix socket權限的用戶,默認和運行的用戶同樣;用tcp鏈接能夠註釋掉

  1. listen.owner = apache
  2. listen.group = apache
  3. listen.mode = 0660

5.0 listen.allowed_clients = 127.0.0.1 設置容許鏈接fpm的地址,好比nginx就要來連,多個地址用逗號隔開,若是不配置,則默認任意地址都能來連。

6.0 process.priority = -19 池進程的權限,一樣要master進程是root用戶纔有效,和全局那個同樣,不設置的話會繼承master進程的優先級。

7.0

  1. pm = dynamic 啓動時子進程管理方式,可選值:static(啓動時建立指定個數), dynamic(啓動時根據狀況建立,至少有一個), ondemand(啓動時不建立子進程,有需求才建立)
  2. pm.max_children = 5 該池同時最多存在5個進程, 三種管理方式都要配置
  3. pm.start_servers = 2 fpm啓動時建立2個子進程,只適用動態dynamic管理方式
  4. pm.min_spare_servers = 2 服務器閒置時最少保持2個子進程,不夠這個數就會建立,只適用動態dynamic管理方式
  5. pm.max_spare_servers = 3 服務器閒置時最多要有幾個,多了會kill,只適用動態dynamic管理方式
  6. pm.process_idle_timeout = 10s; 子進程閒置10s後就會被殺掉。

8.0 pm.max_requests = 500 每一個子進程最大處理500請求就被回收,可防止內存泄露。

9.0 有幾個設置,能夠看fpm的status,和nginx的差很少。

10.0 access.log = var/log/$pool.access.log 訪問文件日誌,沒啥用處,好比yii2每次都記錄訪問index.php,只是記錄真實的PHP文件。

11.0 slowlog = var/log/$pool.log.slow PHP文件執行過慢的日誌,會準確的記錄具體哪一行代碼太慢,這個很是有用,在設置了時間時生效。

11.1 request_slowlog_timeout = 2s 超過這個運行時間就會寫慢日誌

12.0 request_terminate_timeout = 3s 單個請求的超時時間,有時候php.ini設置的最大執行時間未生效,這個就會來幹掉那個執行過久的請求。

13.0 rlimit_files = 1024 最大打開句柄數,默認爲系統值。

14.0 rlimit_core = 0 最多的核心使用數,默認爲系統分配。

15.0 chroot = /path 路徑必須是絕對路徑,改變子進程的跟目錄,能夠把進程對文件系統的讀寫與實際的操做系統文件系統隔離,對安全有好處。

16.0 chdir = /var/www 改變當前工做目錄,能夠用相對路徑,默認是當前目錄或者chroot。

17.0 catch_workers_output = yes 重定向標準輸出stdout和標準錯誤stderr到主錯誤日誌,若是不設置,這兩個日誌就會定向到/dev/null,在高負載狀況下,這個配置會引發頁面延遲幾毫秒,默認不開啓。

18.0 clear_env = no 建立work進程時是否清除環境變量,若是是yes,那麼該子進程 getenv() 就訪問不到 $_ENV$_SERVER 了。

19.0 security.limit_extensions = .php .php3 .php4 .php5 爲了安全,限制能執行的腳本後綴

20.0 爲當前池指定另外的 php.ini 配置,好比指定當前池的錯誤日誌寫在哪一個地方

  1. php_value/php_flag 能夠設置php.ini的內容,能夠被ini_set覆蓋
  2. php_admin_value/php_admin_flag 這個同上,可是不會被ini_set覆蓋。
  3. 其中flag設置的,值只能是on, off, 1, 0, true, false, yes or no,其餘類型的值須要用value。
  4. php_flag[display_errors] = off
  5. php_admin_value[error_log] = /var/log/fpm-php.www.log
  6. php_admin_flag[log_errors] = on
  7. php_admin_value[memory_limit] = 32M
  8. 這種方法設置 `disable_functions` 和 `disable_classes` 時,不會覆蓋 php.ini 的設置,只會追加。

注意:PHP配置值經過 php_value 或者 php_flag 設置,而且會覆蓋之前的值。請注意 disable_functions 或者 disable_classes 在 php.ini 之中定義的值不會被覆蓋掉,可是會將新的設置附加在原有值的後面。
使用 php_admin_value 或者 php_admin_flag 定義的值,不能被 PHP 代碼中的 ini_set() 覆蓋。

自 5.3.3 起,也能夠經過 web 服務器設置 PHP 的設定。

nginx 經過 unixsock 與 php-fpm 通訊:

適用場景:nginx和php-fpm在同一臺服務器上,這時能夠直接用unixsocket進程間通訊,不走tcp端口通訊,能夠節約建立鏈接的時間,從而提升性能。

一、設置php-fpm的listen爲/opt/remi/php56/root/var/run/php-fpm/php567-fpm.sock(能夠用相對路徑),而後重啓fpm就會自動建立該php567-fpm.sock文件

二、nginx的fastcgi_pass參數修改成 unix:/opt/remi/php56/root/var/run/php-fpm/php567-fpm.sock; 經過php567-fpm.sock文件去和fpm通訊,須要保證該 php567-fpm.sock 文件 nginx 有權限訪問。

總結:

sock文件隨便建立到哪裏均可以,只要fpm有權限在那個目錄裏寫文件,nginx有權限去讀就能夠。tcp鏈接會更穩定,由於有tcp協議保證數據的正確性,可是sock有更少的數據拷貝和上下文切換,更少的資源佔用。不過只能在nginx和fpm在同一臺機器上才能用sock。

fpm進程狀態監控

一、nginx配置:遇到 status 的請求,直接轉發給php

location ~^/status$ {
    fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
}

二、fpm配置:pm.status_path = /status

三、而後從新fpm和nginx,在瀏覽器裏訪問就能看到了:

默認以 text/plain 展現結果,能夠傳參數 ?json/html/xml 分別獲得json等格式的結果;參數full能夠查看每一個子進程的明細

  1. pool 進程池名稱
  2. process manager 進程管理方式
  3. start time 進程何時啓動的
  4. start since 進程已經運行了多少秒
  5. accepted conn 該池總共accept了多少鏈接
  6. listen queue 等待accept的鏈接的數量
  7. max listen queue fpm啓動後,歷史最高等待accept的鏈接的數量
  8. listen queue len 配置的監聽隊列最大長度 受限於`listen.backlog`和系統`cat /proc/sys/net/core/somaxconn`,二者中取最小值
  9. idle processes 閒置的進程數
  10. active process 正在工做的進程數(加上限制的,就是總的子進程數)
  11. total processes 總的子進程數量
  12. max active processes fpm啓動後,歷史最多同時工做的進程數
  13. max children reached 進程管理模式爲 'dynamic'和 'ondemand'時,此數值是當子進程不夠用時,master建立更多子進程的次數
  14. slow requests 慢請求個數
  15.  
  16. full參數下
  17. pid 子進程ID;
  18. state 子進程狀態(Idle, Running, ...);
  19. start time 子進程啓動的時間;
  20. start since 子進程啓動後運行了多少秒;
  21. requests 當前子進程一共處理了多少個請求;
  22. request duration 請求耗費的納秒數;
  23. request method 請求方法 (GET, POST, ...);
  24. request URI 請求參數;
  25. content length POST請求時,請求的內容長度;
  26. user - the user (PHP_AUTH_USER) (or '-' if not set);
  27. script 請求的哪一個php文件;
  28. last request cpu 上次請求耗費的cpu資源
  29. last request memory 上次請求耗費的內存峯值
  30. 若是進程是閒置狀態,那這些信息記錄的就是上次請求的相關數據,不然就是當前本次請求的相關數據。

backlog配置問題

一個fpm子進程在同一時間只能處理一個請求,若是,backlog設置得過大,nginx之類的客戶端發起的請求一直沒有fpm子進程進行accept,nginx就會直接斷掉這個鏈接,等fpm忙過來了再去accept的時候,就會發現斷開了,因而報錯。backlog設置得太小,訪問量大時fpm子進程所有處於忙碌狀態,backlog也塞滿了,就會拒絕新的鏈接,此時nginx再請求,就會直接被拒。因此須要合理的設置backlog參數。

相關文章
相關標籤/搜索