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

本篇文章带大家聊聊PHP配置文件,解析一下配置文件(php.ini 和 php-fpm.conf)中的几种超时相关的配置,希望能够给大家提供帮助!

本篇文章带大家聊聊PHP配置文件,解析一下配置文件(php.iniphp-fpm.conf)中的几种超时相关的配置,希望能够给大家提供帮助!

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

php零基础到就业直播视频课:进入学习Apipost-比 postman 更好用的 API 文档、设计、调试、自动化测试一体化协作平台!点击使用

一、概要

php.ini 和 php-fpm.conf 中有很多超时相关的配置,那么这些配置到底有什么作用呢?在源码中又是怎么实现的呢?这篇文章就来讲讲下面几种超时配置:

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: 配置的可被设定范围

这些模式决定着一个 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,修改函数为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。
浅析PHP配置文件中的几种超时配置

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怎么去掉字符串两端的中括号

原创2022-03-07 11:18:171503 + php学习QQ群:609135716

php去掉字符串两端中括号的方法:1、使用ltrim()函数去除字符串左端的中括号;2、使用rtrim()函数去除字符串右端的中括号,语法为“ltrim(rtrim($str,"]"),"[")”。

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

php零基础到就业直播视频课:进入学习Apipost-比 postman 更好用的 API 文档、设计、调试、自动化测试一体化协作平台!点击使用

本教程操作环境:windows7系统、PHP7.1版、DELL G3电脑

php去掉字符串两端的中括号

在PHP中,可以使用ltrim()和rtrim()函数来去掉字符串两端的中括号

  • ltrim()函数可以去除字符串左端的中括号

  • rtrim()函数可以去除字符串右端的中括号

示例:

<?php
header("Content-type:text/html;charset=utf-8");
$str="[0jjhh45678fg0]";
echo ltrim($str,"[")."<br>";
echo rtrim($str,"]")."<br>";
echo ltrim(rtrim($str,"]"),"[");
?>

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

以上就是php怎么去掉字符串两端的中括号的详细内容,更多请关注钦钦技术栈其它相关文章!

转载至:php中文网【www.php.cn】

版权声明:本文(即:原文链接:https://www.qin1qin.com/catagory/24779/)内容由互联网用户自发投稿贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 630367839@qq.com 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年9月22日 上午11:48
下一篇 2022年9月22日 上午11:52
软件定制开发公司

相关阅读

发表回复

登录后才能评论
通知:禁止投稿所有关于虚拟货币,币圈类相关文章,发现立即永久封锁账户ID!