概述
这是源码php7系列的第三篇文章,主要介绍PHP运行的生命周期、FastCGI、Fpm和Nginx的调用,彻底学透底层知识是解决问题的根本。
CLI模式下的生命周期
CLI模式小生命周期:模块初始化阶段->请求初始化阶段->脚本执行阶段->请求关闭阶段->模块关闭阶段
1.php初始化部分函数调用
- 1.对sapi_globals中的成员变量做初始化(sapi_initialize_empty_request)
- 2.调用sapi_module里面的active方法(sapi_activate)
- 3.初始化output相关变量(php_output_startup)
- 4.对tick_function进行初始化(php_startup_ticks)
- 5.对gc_globals_ctor进行初始化(gc_globals_ctor)
- 6.初始化内存管理,初始化cwd_globals,启动扩展机制,设置一些工具函数,设置词法和语法函数,初始化zend虚拟机的handler,已经对全局变量的初始化等(zend_startup)
- 7.注册析构list(zend_register_list_destructors_ex)
- 8.计算php执行的二进制程序的路径(php_binary_init)
- 9.初始化输出相关的预定义常量(php_output_register_constants)
- 10.注册文件上传相关的预定义常量(php_rfc1867_register_constants)
- 11.初始化配置信息,同时调用zend_parse_ini_file解析php.ini里面的配置(php_init_config)
- 12.注册zend_ini_entries(zend_register_ini_entries)
- 13.注册GET/POST/COOKIE/SERVER/ENV/REQUEST/FILE自动的全局变量(php_startup_auto_globals)
- 14.设置utility values(zend_set_utility_values)
- 15.初始化SAPI对于不同类型内容的处理函数(php_startup_sapi_content_types)
- 16.注册内部扩展(php_register_internal_extensions)
- 17.启动附加的php扩展(php_register_extensions_bc)
- 18.加载所有外部扩展(php_ini_register_extensions)
- 19.对模块进行排序,并检测是否注册到module_register HASH表里
- 20.来启动各个模块(zend_startup_extensions)
- 21.注册附件的函数(zend_register_function)
- 22.禁用php.ini配置要禁用的函数和类
2.详解php_request_startup阶段
php_request_startup是请求级别的操作,每请求一次就执行一次。
php_request_startup执行过程:
- 1.重置输出全局并设置输出处理程序的堆栈(php_output_activate)
- 2.重置垃圾回收(gc_reset)
- 3.初始化编译器(init_compiler)
- 4.初始化执行器(init_executor)
- 5.初始化扫描器
- 6.调用sapi_module里面的activate方法(sapi_activate)
- 7.对信号进行处理
- 8.设置超时时间(zend_set_timeout)
- 9.初始化相关全局变量
- 10.调用request_startup_func激活模块
3.详解执行和管理阶段
执行和管理阶段是PHP生命周期最核心的地方,但是它并不复杂,执行步骤如下:
- 1.complie_file
- 2.读取PHP代码内容,并将词法分析指针指向第一个位置
- 3.通过词法和语法分析生成AST(抽象语法树),赋值到CG(ast)
- 4.初始化op_array
- 5.将AST转化为op_array
- 6.设置op_array中对应Zend虚拟机的handler
- 7.在Zend虚拟机中执行op_array
FPM的三种模式
在讨论FPM模式之前先了解一下,相关知识点:
查看配置文件,安装目录/etc/php-fpm.conf.default 这里,看include的值
include=/usr/local/php7.1.0/etc/php-fpm.d/*.conf
静态模式
fpm的静态模式只要设置2个参数,启动8个work进程等待客户端的请求。
pm = static // 设置静态模式
pm.max_children = 8 //设置work进程数
找到配置文件etc/php-fpm.d/www.conf ,中的pm、pm.max_children的值,启动fpm服务:
/usr/local/php7.1.0/sbin/php-fpm -c etc/php-fpm.conf
查看进程,停止服务用kill PID(进程号)
[root@dd2065d03db8 php7.1.0]# ps aux | grep fpm
root 67 0.0 0.3 47072 6828 ? Ss 08:18 0:00 php-fpm: master process (/usr/local/php7.1.0/etc/php-fpm.conf)
nobody 68 0.0 0.2 47072 5904 ? S 08:18 0:00 php-fpm: pool www
nobody 69 0.0 0.2 47072 5904 ? S 08:18 0:00 php-fpm: pool www
nobody 70 0.0 0.2 47072 5904 ? S 08:18 0:00 php-fpm: pool www
nobody 71 0.0 0.2 47072 5904 ? S 08:18 0:00 php-fpm: pool www
nobody 72 0.0 0.2 47072 5908 ? S 08:18 0:00 php-fpm: pool www
nobody 73 0.0 0.2 47072 5908 ? S 08:18 0:00 php-fpm: pool www
nobody 74 0.0 0.2 47072 5892 ? S 08:18 0:00 php-fpm: pool www
nobody 75 0.0 0.2 47072 5908 ? S 08:18 0:00 php-fpm: pool www
root 77 0.0 0.0 9104 908 pts/1 S+ 08:18 0:00 grep --color=auto fpm
动态模式
fpm的动态模式启动时work个数取决于pm.start_servers参数,当请求量变大时迅速增长,最大work数等于 pm.max_children + pm.start_servers
pm = dynamic
pm.max_children = 20
pm.start_servers = 2
fpm的生命周期
如果直接kill PID掉php-fpm的master进程,服务会直接停止,如果执行的是kill -9 PID 是可以访问的,直到进程没有请求,被服务器回收停止,如果kill掉php-fpm的子进程,服务是会继续提供服务的,php-fpm是负责管理进程,不参与处理请求,work才是处理请求的进程。
|