以PHP7爲學習基礎,PHP7的源碼爲C編寫的。
參考書籍:《PHP內核剖析》秦鵬/著
GitHub網頁:https://github.com/pangudashu/php7-internal/blob/master/1/fpm.md
正文:
worker進程,即PHP Fpm採用多線程模式下,進行服務請求處理的子進程。
fpm_run()
執行後將fork出worker進程,worker進程返回main()
中繼續向下執行,後面的流程就是worker進程不斷accept請求,然後執行PHP腳本並返回,繼續監聽等待新的請求到達。整體流程如下:
(1)等待請求: worker進程阻塞在fcgi_accept_request()等待請求;
(2)解析請求: fastcgi請求到達後被worker接收,然後開始接收並解析請求數據,直到request數據完全到達;
(3)請求初始化: 執行php_request_startup(),此階段會調用每個擴展的:PHP_RINIT_FUNCTION();
(4)編譯、執行: 由php_execute_script()完成PHP腳本的編譯、執行;
(5)關閉請求: 請求完成後執行php_request_shutdown(),此階段會調用每個擴展的:PHP_RSHUTDOWN_FUNCTION(),然後進入步驟(1)等待下一個請求。
int main(int argc, char *argv[])
{
...
fcgi_fd = fpm_run(&max_requests);
parent = 0;
//初始化fastcgi請求
request = fpm_init_request(fcgi_fd);
//worker進程將阻塞在這,等待請求
while (EXPECTED(fcgi_accept_request(request) >= 0)) {
SG(server_context) = (void *) request;
init_request_info();
//請求開始
if (UNEXPECTED(php_request_startup() == FAILURE)) {
...
}
...
fpm_request_executing();
//編譯、執行PHP腳本
php_execute_script(&file_handle);
...
//請求結束
php_request_shutdown((void *) 0);
...
}
...
//worker進程退出
php_module_shutdown();
...
}
worker進程一次請求的處理被劃分爲5個階段:
FPM_REQUEST_ACCEPTING: 等待請求階段
FPM_REQUEST_READING_HEADERS: 讀取fastcgi請求header階段
FPM_REQUEST_INFO: 獲取請求信息階段,此階段是將請求的method、query stirng、request uri等信息保存到各worker進程的fpm_scoreboard_proc_s結構中,此操作需要加鎖,因爲master進程也會操作此結構
FPM_REQUEST_EXECUTING: 執行請求階段
FPM_REQUEST_END: 沒有使用
FPM_REQUEST_FINISHED: 請求處理完成
worker處理到各個階段時將會把當前階段更新到fpm_scoreboard_proc_s->request_stage
,master進程正是通過這個標識判斷worker進程是否空閒的。