?
This document uses PHP Chinese website manual Release
請求處理
fpm_run()執(zhí)行后將fork出worker進程,worker進程返回main()中繼續(xù)向下執(zhí)行,后面的流程就是worker進程不斷accept請求,然后執(zhí)行PHP腳本并返回。整體流程如下:
(1)等待請求: worker進程阻塞在fcgi_accept_request()等待請求;
(2)解析請求: fastcgi請求到達后被worker接收,然后開始接收并解析請求數(shù)據(jù),直到request數(shù)據(jù)完全到達;
(3)請求初始化: 執(zhí)行php_request_startup(),此階段會調(diào)用每個擴展的:PHP_RINIT_FUNCTION();
(4)編譯、執(zhí)行: 由php_execute_script()完成PHP腳本的編譯、執(zhí)行;
(5)關閉請求: 請求完成后執(zhí)行php_request_shutdown(),此階段會調(diào)用每個擴展的: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(); //編譯、執(zhí)行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: 執(zhí)行請求階段
FPM_REQUEST_END: 沒有使用
FPM_REQUEST_FINISHED: 請求處理完成
worker處理到各個階段時將會把當前階段更新到fpm_scoreboard_proc_s->request_stage,master進程正是通過這個標識判斷worker進程是否空閑的。