關於 PHP-FPM

php-fpm是一種master(主)/worker(子)多進程架構,與nginx設計風格有點類似。master進程主要負責CGI及PHP環境初始化、事件監聽、子進程狀態等等,worker進程負責處理php請求。

 

運行模式

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

static : 靜態模式,啓動時分配固定的worker進程。 

ondemand: 按需分配,當收到用戶請求時fork worker進程。 

dynamic: 動態模式,啓動時分配固定的進程。伴隨着請求數增加,在設定的浮動範圍調整worker進程。

 

 

master進程

master進程工作流程分爲4個階段

1. cgi初始化階段:分別調用fcgi_init()和 sapi_startup()函數,註冊進程信號以及初始化sapi_globals全局變量。 

2. php環境初始化階段:由cgi_sapi_module.startup 觸發。實際調用php_cgi_startup函數,而php_cgi_startup內部又調用php_module_startup執行。 php_module_startup主要功能:a).加載和解析php配置;b).加載php模塊並記入函數符號表(function_table);c).加載zend擴展 ; d).設置禁用函數和類庫配置;e).註冊回收內存方法; 

3. php-fpm初始化階段:執行fpm_init()函數。負責解析php-fpm.conf文件配置,獲取進程相關參數(允許進程打開的最大文件數等),初始化進程池及事件模型等操作。 

4. php-fpm運行階段:執行fpm_run() 函數,運行後主進程發生阻塞。該階段分爲兩部分:fork子進程 和 循環事件。fork子進程部分交由fpm_children_create_initial函數處理( 注:ondemand模式在fpm_pctl_on_socket_accept函數創建)。循環事件部分通過fpm_event_loop函數處理,其內部是一個死循環,負責事件的收集工作。

 

worker進程

worker進程分爲 接收客戶端請求、處理請求、請求結束三個階段

1. 接收客戶端請求:執行fcgi_accept_request函數,其內部通過調用accept 函數獲取客戶端請求。

2. 處理請求階段:首先,分別調用fpm_request_info、php_request_startup獲取請求內容及註冊全局變量($_GET、$_POST、$_SERVER、$_ENV、$_FILES);然後根據請求信息調用php_fopen_primary_script訪問腳本文件;最後交給php_execute_script執行。php_execute_script內部調用zend_execute_scripts方法將腳本交給zend引擎處理。 

3. 請求結束階段:執行php_request_shutdown函數。此時 回調register_shutdown_function註冊的函數及__destruct()方法,發送響應內容、釋放內存等操作。

 

 

 

web server(比如說nginx)只是內容的分發者。比如,如果請求/index.html,那麼web server會去文件系統中找到這個文件,發送給瀏覽器,這裏分發的是靜態數據。好了,如果現在請求的是/index.php,根據配置文件,nginx知道這個不是靜態文件,需要去找PHP解析器來處理,那麼他會把這個請求簡單處理後交給PHP解析器。Nginx會傳哪些數據給PHP解析器呢?url要有吧,查詢字符串也得有吧,POST數據也要有,HTTP header不能少吧,好的,CGI就是規定要傳哪些數據、以什麼樣的格式傳遞給後方處理這個請求的協議。

 

當web server收到/index.php這個請求後,會啓動對應的CGI程序,這裏就是PHP的解析器。接下來PHP解析器會解析php.ini文件,初始化執行環境,然後處理請求,再以規定CGI規定的格式返回處理後的結果,退出進程。web server再把結果返回給瀏覽器。

 

"PHP解析器會解析php.ini文件,初始化執行環境"。標準的CGI對每個請求都會執行這些步驟,所以處理每個時間的時間會比較長。那麼Fastcgi是怎麼做的呢?首先,Fastcgi會先啓一個master,解析配置文件,初始化執行環境,然後再啓動多個worker。當請求過來時,master會傳遞給一個worker,然後立即可以接受下一個請求。這樣就避免了重複的勞動,效率自然是高。而且當worker不夠用時,master可以根據配置預先啓動幾個worker等着;當然空閒worker太多時,也會停掉一些,這樣就提高了性能,也節約了資源。這就是fastcgi的對進程的管理。

 

PHP的解釋器是php-cgi。php-cgi只是個CGI程序,他自己本身只能解析請求,返回結果,不會進程管理,所以就出現了一些能夠調度php-cgi進程的程序,比如說由lighthttpd分離出來的spawn-fcgi。好了PHP-FPM也是這麼個東西,在長時間的發展後,逐漸得到了大家的認可(要知道,前幾年大家可是抱怨PHP-FPM穩定性太差的),也越來越流行。

 

fastcgi是一個協議,php-fpm實現了這個協議。

發佈了117 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章