新聞中心
本篇文章帶大家聊聊php配置文件,解析一下配置文件(php.ini 和 php-fpm.conf)中的幾種超時(shí)相關(guān)的配置,希望能夠給大家提供幫助!

梁子湖網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)建站于2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
php.ini 和 php-fpm.conf 中有很多超時(shí)相關(guān)的配置,那么這些配置到底有什么作用呢?在源碼中又是怎么實(shí)現(xiàn)的呢?這篇文章就來講講下面幾種超時(shí)配置:
php.ini
- max_execution_time
- max_input_time
php-fpm.conf
- process_control_timeout
- request_terminate_timeout
- request_slowlog_timeout
運(yùn)行環(huán)境: Mac 10.14.2 + PHP 7.3.7
二、配置解析規(guī)則
解析規(guī)則
php.ini的解析是在php_module_startup()階段完成,ini_entry是在 main.c 中為每個(gè)php.ini配置定義的解析規(guī)則,格式如下:
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)
參數(shù)解釋
name: 配置名稱
default_value: 配置默認(rèn)值
modifiable: 配置的可被設(shè)定范圍
on_modify: 配置修改函數(shù)
三、max_input_time、max_execution_time
因?yàn)?code>max_input_time 和 max_execution_time 聯(lián)系比較密切,所以放在一起來講。
php.ini 解釋
配置解析規(guī)則
// max_input_time,默認(rèn)值為無限制
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,默認(rèn)值為30s,修改函數(shù)為OnUpdateTimeout
PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout)
OnUpdateTimeout()函數(shù)如下,由第二節(jié)可知配置解析發(fā)生在php_module_startup()階段,此時(shí)EG(timeout_seconds)被賦值為了max_execution_time,但還沒有設(shè)置定時(shí)器。
// 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;
}
設(shè)置超時(shí)定時(shí)器
// 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);
}
......
}
從上面代碼可以看到,如果設(shè)置了max_input_time(即值不等于-1,-1可以認(rèn)為是在CLI模式下),在php_request_startup()階段會(huì)設(shè)置一個(gè)定時(shí)器,超時(shí)時(shí)間為max_input_time;在php_execute_script()階段會(huì)重新設(shè)置一個(gè)定時(shí)器,超時(shí)時(shí)間為max_execution_time。那么整個(gè)PHP腳本執(zhí)行的最大執(zhí)行時(shí)間就等于max_input_time + max_execution_time。
如果沒有設(shè)置max_input_time的話(即值等于-1),在php_request_startup()階段也會(huì)設(shè)置一個(gè)定時(shí)器,但超時(shí)時(shí)間被設(shè)為了EG(timeout_seconds),而EG(timeout_seconds)已經(jīng)在php_module_startup()階段被賦值為max_execution_time,所以此時(shí)的超時(shí)時(shí)間就是max_execution_time;在php_execute_script()階段不會(huì)重新設(shè)置定時(shí)器,前一階段設(shè)置的max_execution_time定時(shí)器仍然生效著。那么整個(gè)PHP腳本的最大執(zhí)行時(shí)間就是max_execution_time。
zend_set_time() 使用setitimer(ITIMER_PROF, &t_r, NULL); 來實(shí)現(xiàn)定時(shí)器,ITIMER_PROF會(huì)統(tǒng)計(jì)包括用戶態(tài)和內(nèi)核態(tài)下所花費(fèi)的時(shí)間,而像sleep()這樣的系統(tǒng)調(diào)用會(huì)讓進(jìn)程掛起,不占用cpu時(shí)間片,所以這倆超時(shí)時(shí)間是不包括sleep()時(shí)間的。
當(dāng)定時(shí)器到時(shí)間后,ZendVM會(huì)拋出E_ERROR,即Fatal error錯(cuò)誤。
四、process_control_timeout
php-fpm.conf 解釋
分析
當(dāng)master進(jìn)程接收到SIGINT、SIGTERM、SIGQUIT、SIGUSR2這些信號(hào)時(shí),會(huì)調(diào)用fpm_pctl()來進(jìn)行處理。
首先master進(jìn)程會(huì)根據(jù) 接收到的信號(hào) 和 當(dāng)前fpm的運(yùn)行狀態(tài) 來決定發(fā)送給worker進(jìn)程的是SIGQUIT還是SIGTERM信號(hào),同時(shí)注冊時(shí)間為process_control_timeout的定時(shí)事件。
如果在process_control_timeout時(shí)間內(nèi)子進(jìn)程沒有退出,那么master進(jìn)程會(huì)升級(jí)SIGQUIT為SIGTERM,SIGTERM為SIGKILL,并注冊1s的定時(shí)事件。SIGKILL就直接終止worker進(jìn)程了,SIGTERM還能再給worker進(jìn)程1s的時(shí)間。
綜上,process_control_timeout可以理解為master進(jìn)程留給worker進(jìn)程結(jié)束自己的時(shí)間,要是到時(shí)間worker還沒搞定那就開始master自己的策略了。
五、request_terminate_timeout、request_slowlog_timeout
因?yàn)?code>request_terminate_timeout 和 request_slowlog_timeout 聯(lián)系比較密切,所以放在一起來講。
php-fpm.conf 解釋
分析
request_slowlog_timeout 和 request_terminate_timeout 用在master進(jìn)程的心跳檢測中(fpm_pctl_heartbeat()),心跳時(shí)間heartbeat 簡化后的算法是
-
在開啟
request_terminate_timeout情況下:request_terminate_timeout/1000*3 -
在未開啟
request_terminate_timeout情況下:request_slowlog_timeout/1000*3或者 0 -
request_terminate_timeout >= request_slowlog_timeout
第三條規(guī)則是為了保證slowlog不影響到正常的請求,heartbeat 取超時(shí)時(shí)間的1/3應(yīng)該是為了避免心跳檢測過于頻繁,因?yàn)槊看涡奶鴻z測都需要遍歷所有worker進(jìn)程。
如果超時(shí)事件發(fā)生了,那么將直接kill掉worker進(jìn)程,kill(child_pid, SIGTERM); ,之后內(nèi)核回收資源關(guān)閉client_socket,nginx返回502錯(cuò)誤給瀏覽器。
文章名稱:淺析PHP配置文件中的幾種超時(shí)配置
網(wǎng)站鏈接:http://www.5511xx.com/article/cdcspes.html


咨詢
建站咨詢
