深刻了解SAPI

1、SAPI比較

1. SAPI

服務器應用程序編程接口,就是服務器與編程語言之間交互的接口。好比Linux命令行執行一段PHP代碼,實際上是Linux shell經過PHP SAPI傳入一組參數,zend引擎執行後返回給shell。在PHP生命週期的各個階段,一些與服務相關的操做都是經過SAPI接口實現。php

php_sapi_name()能夠查看當前SAPI接口的類型。  
如 cli(php -r "echo php_sapi_name();")、fpm-fcgi等

2. PHP運行和加載的4個階段

①Minit 模塊初始化階段,能夠初始化php擴展、類庫的內部變量、註冊常量,定義模塊使用的類等。html

②Rinit 請求初始化階段,在模塊初始化並激活後,會建立PHP運行環境,初始化本次請求所需的環境變量,好比 $_SERVER,$_SESSIONmysql

③Rshutdown 請求關閉階段,執行最後的清理工做,釋放全部處理本次請求的資源(申請的變量)。請求完成多是執行到腳本完成,也多是調用die()或exit()函數完成nginx

④Mshutdown 模塊回收階段,用於關閉本身的內核子系統,釋放沒存。sql

3. SAPI 5種運行模式

①單進程模式(CLI,CGI),每次執行PHP腳本,都會執行第二部分講的四個INT和Shutdown事件。當用戶請求數量很是多時,會大量擠佔系統的資源如內存,CPU時間等,形成系統開銷很大
clipboard.pngshell

②多進程模式(Apache下的prefork MPM模式),會fork不少子進程,每一個子進程擁有本身獨立的進程地址空間,在一個子進程中,PHP的生命週期是調用MINT啓動後,執行屢次請求(RINT/RSHUTDOWN),在Apache關閉或進程結束後,纔會調用MSHUTDOWN進行回收階段。
多進程模型中,每一個子進程都是獨立運行,沒有代碼和數據共享,所以一個子進程終止退出和從新生成,不會影響其餘子進程的穩定。數據庫

clipboard.png

clipboard.png

③多線程模式(Apache2的Worker MPM),在一個進程下建立多個線程,在同一個進程地址空間執行編程

clipboard.png

④fastCGI模式,nginx+php-fpm就是這個模式,fast-cgi是CGI的升級版本,FastCGI能夠當作是一個常駐型的CGI,它能夠一直執行着,運行後能夠fork多個進程,不用花費時間動態Fork子進程。也不須要每次請求都調用MINT/MSHUTDOWN。
⑤內嵌模式,容許在C/C++語言中調用PHP提供的函數,運行模式和CGI同樣,執行4個階段vim

2、php-fpm運行原理

  • CGI:是個協議,服務器發起請求,傳給PHP解析器,傳遞哪些數據,以什麼格式,由CGI決定
  • fastcgi:是個協議,提升CGI性能的,不用每次都去初始化,進程不夠用,會預先啓動幾個進程,進程空閒太多了也會停掉一些,fastCGI對進程的管理,提升性能,節約了資源
  • php-fpm:實現fastCGI協議的程序,被PHP官方收了,也提供了進程管理功能,進程包含 master 進程和 worker 進程兩種進程。 master 進程只有一個,負責監聽端口分發請求,接收來自 Web Server 的請求,而 worker 進程則通常有多個(具體數量根據實際須要配置),每一個進程內部都嵌入了一個 PHP 解釋器,是 PHP 代碼真正執行的地方。
  • php-cgi:cgi解釋器進程

FastCGI的工做原理:api

  1. Web Server啓動時載入FastCGI進程管理器
  2. FastCGI進程管理器自身初始化,啓動多個CGI解釋器(可見多個php-cgi)並等待來自Web Server的鏈接
  3. 當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web Server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi
  4. FastCGI子進程完成處理後將標準輸出和錯誤信息從同一鏈接返回Web Server。當FastCGI子進程關閉鏈接時,請求便告知處理完成。FastCGI子進程接着等待並處理來自FastCGI繼承管理器的下一個鏈接

使用FastCGI,系統開銷小。另外,對於數據庫和Memcache的持續鏈接能夠工做。

數據庫短鏈接connect:請求關閉階段,釋放請求所用的資源,數據庫鏈接句柄也會被釋放

數據庫長鏈接pconnect:請求關閉後,PHP會收留這次鏈接,即便主動關閉也不會關閉而是收留,下次有打開相同鏈接的請求時,PHP直接把收留的句柄拿出來,省去創建鏈接的過程。

php-fpm實現長鏈接也須要配合數據庫一些配置,一個進程收留一個鏈接,數據庫鏈接的數量就是子進程數量,因此數據庫容許鏈接數就要大於子進程數。

clipboard.png

3、php-fpm進程管理的三種模式

php-fpm支持三種運行模式,分別爲static、ondemand、dynamic,默認爲dynamic 。

  • static : 靜態模式,啓動時分配固定的worker進程。只須要考慮max_children的數量,數量取決於cpu的個數和應用的響應時間。
  • ondemand: 按需分配,啓動時不分配任何進程,當收到用戶請求時才啓動進程。 master進程檢查work進程的數量是否受限,是否有空閒的work進程,沒有就新建work進程。在大流量的系統上master進程會變得繁忙,佔用系統cpu資源,不適合大流量環境的部署。
  • dynamic: 動態模式,啓動時分配固定的進程。伴隨着請求數增長,在設定的浮動範圍調整worker進程。
pm = dynamic  //動態進程管理,對於專用服務器,能夠設置爲static,靜態一次性啓動最大子進程數,不會變化。
 
 pm.max_children = 50 //最大子進程數,ps aux能夠查看
 
 pm.start_servers = 20 //啓動服務時會啓動的進程數
 
 pm.min_spare_servers = 5 //保證空閒子進程數的最小值,若是空閒進程小於這個值,php-fpm服務會建立新的子進程。
 
 pm.max_spare_servers = 35 //保證空閒子進程數的最大值,若是空閒進程高於這個值,就進行清理。
 
 pm.max_requests = 500  //定義一個子進程最多處理的請求數,達到這個值,進程自動退出。目的是爲了控制內存溢出,使內存在一個可控範圍內。可是若是設置的很小,有可能多個進程同時達到這個值,同時重啓,就會致使PHP中止響應直到重啓完畢。設置爲0表示一直接受請求。

4、php-fpm慢日誌

若是一個php網站能夠訪問,就是訪問速度變慢了,能夠經過php-fpm的慢執行日誌,清晰的瞭解到php的腳本哪裏執行時間長,它能夠定位到具體的代碼行

vim /usr/local/php/etc/php-fpm.d/www.conf
 request_slowlog_timeout = 1 //超時時間
 slowlog = /usr/local/php/var/log/www-slow.log
 重啓php-fpm /etc/init.d/php-fpm reload

我在php文件中加了一行sleep(3);,運行以後返回結果

clipboard.png

圖片描述

參考文獻

一、https://www.jianshu.com/p/c9a... php-fpm進程管理的三種模式
二、https://www.jb51.net/article/... SAPI的5種運行模式
三、http://blog.51cto.com/1260661... php-fpm慢日誌
四、https://www.cnblogs.com/wpjam... php-fpm與mysql長鏈接

相關文章
相關標籤/搜索