PHP配置文件的几种时配置
一、概要
php.ini
- max_execution_time
- max_input_time
php-fpm.conf
- process_control_timeout
- request_terminate_timeout
- request_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: 配置的可被设定范围
on_modify: 配置修改函数
三、max_input_time、max_execution_time
因为max_input_time
和 max_execution_time
联系比较密切,所以放在一起来讲。
php.ini 解释
配置解析规则
// 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,修改函数为OnUpdateTimeout
PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout)
OnUpdateTimeout()
函数如下,由第二节可知配置解析发生在php_module_startup()
阶段,此时EG(timeout_seconds)
被赋值为了max_execution_time
,但还没有设置定时器。
// main.c
static 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.c
int 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_timeout
php-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错误给浏览器。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanfhgkk
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01