当前位置: 首页 > 后端技术 > PHP

[PHP]配置文件超时时间分析

时间:2023-03-30 05:57:10 PHP

一、概述php.ini和php-fpm.conf中有很多超时相关的配置,那么这些配置的作用是什么呢?它在源代码中是如何实现的?本文将讲到以下超时配置:php.inimax_execution_timemax_input_timephp-fpm.confprocess_control_timeoutrequest_terminate_timeoutrequest_slowlog_timeout运行环境:Mac10.14.2+PHP7.3.7二、配置解析规则php.ini的解析在php_module_startup()阶段完成,ini_entry是main.c中为每一个php.ini配置定义的解析规则,格式如下:ZEND_INI_ENTRY3_EX(name,default_value,modifiable,on_modify,arg1,arg2,arg3,displayer)PHP为不同类型的配置定义了很多宏,ZEND_INI_ENTRY3_EX是展开后的最后一个宏,如PHP_INI_ENTRY宏PHP_INI_ENTRY(name,default_value,modifiable,on_modify)参数说明name:配置名称default_value:配置默认值modifiable:配置可设置范围这些模式决定了PHP的Whenandwhere命令可以设置。手册中的每个指令都有它所属的模式。例如,某些指令可以在PHP脚本中使用ini_set()设置,而其他指令只能在php.ini或httpd.conf中设置。例如,output_buffering指令属于PHP_INI_PERDIR,因此不能用ini_set()设置。但是display_errors指令属于PHP_INI_ALL,因此可以在任何地方设置,包括ini_set()。模式含义PHP_INI_USER可以在用户脚本(例如ini_set())或Windows注册表(自PHP5.3)和.user.ini中设置PHP_INI_PERDIR可以在php.ini、.htaccess或httpd.conf中设置PHP_INI_SYSTEM可以在设置PHP_INI_ALL在php.ini或者httpd.conf中可以任意设置on_modify:配置修改函数3.max_input_time,max_execution_time由于max_input_time和max_execution_time关系密切,所以放在一起。php.ini解释max_input_time;每个脚本可能花在解析请求数据上的最长时间。这很好;限制生产服务器上的时间以消除意外的想法;长时间运行的脚本。注意:对于CLISAPI,该指令被硬编码为-1;http://php.net/max-input-time翻译为:max_input_time是每个脚本可以花在解析请求数据上的最长时间。通过限制max_input_time,可以在生产服务器上消除长时间运行的脚本。在CLI模式下,它将被硬编码为-1,这意味着没有限制。最大执行时间;每个脚本的最大执行时间,以秒为单位;http://php.net/max-execution-...;注意:对于CLISAPI翻译,该指令被硬编码为0:max_execution_time是每个脚本执行时间的最大执行时间。CLI模式硬编码为0配置解析规则//max_input_time,默认值无限制STD_PHP_INI_ENTRY("max_input_time","-1",PHP_INI_SYSTEM|PHP_INI_PERDIR,OnUpdateLong,max_input_time,php_core_globals,core_globals)//max_execution_time,默认值30s,修改函数为OnUpdateTimeoutPHP_INI_ENTRY("max_execution_time","30",PHP_INI_ALL,OnUpdateTimeout)OnUpdateTimeout()函数如下,从第二节我们可以看出配置分析发生在php_module_startup()阶段,此时EG(timeout_seconds)被赋值给max_execution_time,但是定时器还没有设置。//main.cstaticPHP_INI_MH(OnUpdateTimeout){if(stage==PHP_INI_STAGE_STARTUP){/*不要在启动时设置超时,只针对每个请求设置*//*EG(timeout_seconds)=max_execution_time*/ZEND_ATOL(EG(timeout_seconds)),ZSTR_VAL(新值));返回成功;}zend_unset_timeout();ZEND_ATOL(EG(timeout_seconds),ZSTR_VAL(new_value));zend_set_timeout(EG(timeout_seconds),0);returnSUCCESS;}设置超时计时器//main.cintphp_request_startup(void){......if(PG(max_input_time)==-1){zend_set_timeout(EG(timeout_seconds),1);}else{zend_set_timeout(PG(max_input_time),1);}。.....}intphp_execute_script(zend_file_handle*primary_file){......if(PG(max_input_time)!=-1){zend_set_timeout(INI_INT("max_execution_time"),0);}......}从上面的代码可以看出,如果设置了max_input_time(即该值不等于-1,CLI模式下可以考虑-1),会在里面设置一个定时器php_request_startup()阶段,超时时间为max_input_time;在php_execute_script()阶段会重置一个定时器,超时时间为max_execution_time。那么整个PHP脚本执行的最大执行时间等于max_input_time+max_execution_time。如果不设置max_input_time(即值等于-1),在php_request_startup()阶段也会设置一个定时器,但是超时时间设置为EG(timeout_seconds),EG(timeout_seconds)已经在php_module_startup()阶段分配了max_execution_time,所以此时超时时间为max_execution_time;php_execute_script()阶段不会重置定时器,前一阶段设置的max_execution_time定时器仍然有效。那么整个PHP脚本的最大执行时间就是max_execution_time。zend_set_time()使用setitimer(ITIMER_PROF,&t_r,NULL);定时器的实现,ITIMER_PROF会统计用户态和内核态的耗时,sleep()等系统调用会挂掉进程,不占用cpu时间片,所以这两个timeout不包括sleep()的时间。当计时器超时时,ZendVM将抛出E_ERROR,这是致命错误。4、process_control_timeoutphp-fpm.conf的解释;子进程等待对来自主进程的信号作出反应的时间限制。可用单位:s(秒)、m(分)、h(我们的)或d(天);默认单位:秒翻译:process_control_timeout是子进程处理主进程信号的剩余时限。分析当master进程收到SIGINT、SIGTERM、SIGQUIT、SIGUSR2等信号时,会调用fpm_pctl()进行处理。首先master进程会根据接收到的信号和fpm当前的运行状态,决定是否向worker进程发送SIGQUIT或SIGTERM信号,同时向process_control_timeout注册定时事件。如果子进程在process_control_timeout时间内没有退出,master进程会将SIGQUIT升级为SIGTERM,SIGTERM升级为SIGKILL,并注册一个1s计时事件。SIGKILL直接终止worker进程,SIGTERM可以再给worker进程1秒。总结一下,process_control_timeout可以理解为master进程留给worker进程自己结束的时间。如果worker进程没有按时完成,那么master自己的策略就会启动。五、request_terminate_timeout、request_slowlog_timeout因为request_terminate_timeout和request_slowlog_timeout关系密切,所以放在一起。php-fpm.conf解释了request_terminate_timeout;工作进程将服务于单个请求的超时时间;被杀。这个选项应该在'max_execution_time'ini选项时使用;由于某种原因不会停止脚本执行。值“0”表示“关闭”。可用单位:s(秒)(默认)、m(分)、h(我们的)或d(天);默认值:0翻译:执行请求超时,在此之后工作进程将被终止。当max_execution_timeini选项由于某种原因无法停止脚本执行时,应使用此选项。request_slowlog_timeout;为单个请求提供服务的超时时间,之后将进行PHP回溯;转储到“slowlog”文件。值“0s”表示“关闭”。可用单位:s(秒)(默认)、m(分钟)、h(我们的)或d(天);默认值:0翻译:执行请求的超时时间,之后将向slowlog文件输出PHP回溯。分析request_slowlog_timeout和request_terminate_timeout用于master进程的心跳检测(fpm_pctl_heartbeat())。heartbeattime心跳的简化算法是当request_terminate_timeout开启时:request_terminate_timeout/1000*3当request_terminate_timeout不开启时:request_slowlog_timeout/1000request_terminate_timeout>=request_slowlog_timeout第三条规则是保证slowlog不影响正常请求。Heartbeat占用1/3的超时时间是为了避免过于频繁的心跳检测,因为每次心跳检测都需要遍历所有worker进程。如果发生超时事件,worker进程会被直接杀掉,kill(child_pid,SIGTERM);之后内核回收资源并关闭client_socket,nginx向浏览器返回502错误。

最新推荐
猜你喜欢