您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

浅析PHP配置文件中的几种超时配置

2024/3/25 14:51:45发布31次查看
本篇文章带大家聊聊php配置文件,解析一下配置文件(php.ini 和 php-fpm.conf)中的几种超时相关的配置,希望能够给大家提供帮助!
一、概要php.ini 和 php-fpm.conf 中有很多超时相关的配置,那么这些配置到底有什么作用呢?在源码中又是怎么实现的呢?这篇文章就来讲讲下面几种超时配置:
php.inimax_execution_timemax_input_timephp-fpm.confprocess_control_timeoutrequest_terminate_timeoutrequest_slowlog_timeout运行环境: mac 10.14.2 + php 7.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 的指令在何时何地,是否能够被设定。手册中的每个指令都有其所属的模式。例如有些指令可以在 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 注册表(自 php 5.3 起)以及 .user.ini 中设定
php_ini_perdir 可在 php.ini,.htaccess 或 httpd.conf 中设定
php_ini_system 可在 php.ini 或 httpd.conf 中设定
php_ini_all 可在任何地方设定
on_modify: 配置修改函数
三、max_input_time、max_execution_time因为max_input_time 和 max_execution_time 联系比较密切,所以放在一起来讲。
php.ini 解释max_input_time; maximum amount of time each script may spend parsing request data. it's a good
; idea to limit this time on productions servers in order to eliminate unexpectedly
; long running scripts.
; note: this directive is hardcoded to -1 for the cli sapi
; http://php.net/max-input-time
翻译过来就是:max_input_time是每个脚本可以花在解析请求数据上的最大时间。在生产服务器上通过限制max_input_time可以清除掉长时间运行的脚本。在cli模式下会硬编码为-1,即无限制。
max_execution_time; maximum execution time of each script, in seconds
; http://php.net/max-execution-...
; note: this directive is hardcoded to 0 for the cli sapi
翻译: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.cstatic php_ini_mh(onupdatetimeout){ if (stage==php_ini_stage_startup) { /* don't set a timeout on startup, only per-request */ /* eg(timeout_seconds) = max_execution_time */ zend_atol(eg(timeout_seconds), zstr_val(new_value)); return success; } zend_unset_timeout(); zend_atol(eg(timeout_seconds), zstr_val(new_value)); zend_set_timeout(eg(timeout_seconds), 0); return success;}
设置超时定时器// main.cint php_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); } ......}int php_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,-1可以认为是在cli模式下),在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时间片,所以这俩超时时间是不包括sleep()时间的。
当定时器到时间后,zendvm会抛出e_error,即fatal error错误。
四、process_control_timeoutphp-fpm.conf 解释; time limit for child processes to wait for a reaction on signals from master.
; available units: s(econds), m(inutes), h(ours), or d(ays)
; default unit: seconds翻译:process_control_timeout是留给子进程处理来自master进程信号的时间限制。
分析当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进程1s的时间。
综上,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; the timeout for serving a single request after which the worker process will
; be killed. this option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. a value of '0' means 'off'.
; available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; default value: 0
翻译:执行一个请求的超时时间,在这之后worker进程将被终止。这个选项应该被用在max_execution_time 这个ini选项由于某些原因不能停止脚本执行的时候。
request_slowlog_timeout; the timeout for serving a single request after which a php backtrace will be
; dumped to the 'slowlog' file. a value of '0s' means 'off'.
; available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; default value: 0
翻译:执行一个请求的超时时间,在这之后一个php的backtrace会被输出到slowlog文件里。
分析request_slowlog_timeout 和 request_terminate_timeout 用在master进程的心跳检测中(fpm_pctl_heartbeat()),心跳时间heartbeat 简化后的算法是
在开启request_terminate_timeout情况下:request_terminate_timeout/1000*3
在未开启request_terminate_timeout情况下:request_slowlog_timeout/1000*3 或者 0
request_terminate_timeout >= request_slowlog_timeout
第三条规则是为了保证slowlog不影响到正常的请求,heartbeat 取超时时间的1/3应该是为了避免心跳检测过于频繁,因为每次心跳检测都需要遍历所有worker进程。
如果超时事件发生了,那么将直接kill掉worker进程,kill(child_pid, sigterm); ,之后内核回收资源关闭client_socket,nginx返回502错误给浏览器。
推荐学习:《php视频教程》
以上就是浅析php配置文件中的几种超时配置的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product