In fact, very early on have wanted to read PHP source code, the main or their relatively lazy, will not be firm enough, has been unable to calm down the heart. Not very busy recently, take advantage of "short" leisure time, look over the dusty "php source" file.
We know that the Web server interacts with the PHP application through the SAPI interface. PHP provides a variety of SAPI interfaces, such as Apache2hander, fastcgi, CLI, and so on. Of course, PHP-FPM is one of them. PHP-FPM is more widely used than other interfaces.
PHP-FPM is a master (master)/worker (sub) multi-process architecture that is somewhat similar to the Nginx design style. The master process is primarily responsible for CGI and PHP environment initialization, event monitoring, subprocess status, and so on, and the worker process is responsible for processing PHP requests.
Before introducing the principle of operation, we first understand several of its operating modes. Run mode
The PHP-FPM supports three modes of operation, Static, OnDemand, dynamic, and dynamic by default.
Static: Statically mode, which allocates a fixed worker process at startup.
OnDemand: On demand, fork the worker process when a user request is received.
Dynamic: Active mode, which assigns fixed processes at startup. With the increase in the number of requests, the worker process is adjusted in the set floating range.
These three modes are different, you can adjust the corresponding configuration according to the environment.
The following into the subject of this article, focusing on PHP-FPM operating principles. Operation Principle
PHP-FPM uses the Master/worker architecture design, which briefly describes the functions of the master and worker process modules. The following is a detailed explanation of how these two modules work. Master Process
The master process workflow is divided into 4 phases, as shown in the following illustration:
1. CGI initialization phase: Call the Fcgi_init () and Sapi_startup () functions separately, register the process signal, and initialize the sapi_globals global variable.
2. PHP Environment Initialization phase: triggered by Cgi_sapi_module.startup. The Php_cgi_startup function is actually called, and php_module_startup execution is invoked inside the php_cgi_startup. Php_module_startup main function: a). Load and parse PHP configuration; load PHP module and enter the function symbol table (function_table), c). load Zend Extension; d). Set disabled functions and class library configuration; e. Register the recovery memory method;
3. PHP-FPM Initialization phase: Executes the fpm_init () function. Responsible for parsing php-fpm.conf file configuration, obtaining process-related parameters (maximum number of files allowed to open process, etc.), initializing process pool and event model.
4. PHP-FPM Run Phase: Execute Fpm_run () function, run the rear of the process blocking. This phase is divided into two parts: fork and circular events. The fork part is handled by the Fpm_children_create_initial function ( Note: OnDemand mode is created in the Fpm_pctl_on_socket_accept function ). The Loop event section is processed by the Fpm_event_loop function, and its internal is a dead loop, responsible for the collection of events. worker Process
The worker process is divided into three stages of receiving client requests, processing requests, and requesting an end .
1. Receive client request: Executes the Fcgi_accept_request function, within which the client request is obtained by calling the Accept function.
Request Lock
Fcgi_lock (req->listen_socket);
REQ->FD = Accept (Listen_socket, (struct sockaddr *) &sa, &len);
Release lock
Fcgi_unlock (req->listen_socket);
From the above code, you can notice that accept has a request for a lock before the operation, so designed to avoid requests to appear "surprise group" phenomenon. Of course, this is an optional option to cancel this feature.
2. Processing Request phase: First, call Fpm_request_info, php_request_startup to obtain request content and register global variables ($_get, $_post, $_server, $_env, $_files) respectively. , then call Php_fopen_primary_script to access the script file based on the request information, and finally give php_execute_script execution. The Php_execute_script internal call zend_execute_scripts method hands the script to the Zend engine for processing.
3. End of Request phase: Execute Php_request_shutdown function. At this point, callback register_shutdown_function registered functions and __destruct () methods, send response content, free memory, and so on. Summary
PHP-FPM uses Master/worker architecture design, master process is responsible for CGI, PHP public environment initialization and event monitoring operations. The worker process is responsible for the processing capabilities of the request. When a worker process processes a request, it is not necessary to initialize the PHP operating environment again, which is one of the reasons why PHP-FPM performance is excellent.