其實很早之前就有想過閱讀PHP源碼,主要還是自己比較懶散,意志不夠堅定,一直無法靜下心。最近不是很忙,趁著“短暫”的閑暇之餘,翻看塵封已久的“PHP源碼”檔案。
我們知道web伺服器與PHP應用之間通過SAPI介面進行互動資料。PHP提供了多種SAPI介面,例如 apache2hander、fastcgi、cli等等。當然,php-fpm也是其中一種。相比其他介面,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進程。
這三種模式各有千秋,大家可以根據不同的環境調整相應的配置。
下面進入本文主題,著重介紹php-fpm運行原理。 運行原理
php-fpm採用master/worker架構設計,前面簡單地描述master和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 函數擷取用戶端請求。
//請求鎖FCGI_LOCK(req->listen_socket);req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len);//釋放鎖FCGI_UNLOCK(req->listen_socket);
從上面的代碼,可以注意到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()方法,發送響應內容、釋放記憶體等操作。 總結
php-fpm採用master/worker架構設計, master進程負責CGI、PHP公用環境的初始化及事件監聽操作。worker進程負責請求的處理功能。在worker進程處理請求時,無需再次初始化PHP運行環境,這也是php-fpm效能優異的原因之一。