検索
ホームページバックエンド開発PHPチュートリアルPHP 構成ファイル内のいくつかのタイムアウト構成の簡単な分析

この記事では、PHP 構成ファイルについて説明し、構成ファイル (php.ini および php-fpm.conf) 内のいくつかのタイムアウト関連の構成を分析します。

PHP 構成ファイル内のいくつかのタイムアウト構成の簡単な分析

1. 概要

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

2. 解析ルールの設定

解析ルール

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_ENTRYMacro

PHP_INI_ENTRY(name, default_value, modifiable, on_modify)
パラメータの説明

name: 設定名

default_value: デフォルト値を設定します

modifiable: 設定の設定可能な範囲

これらのモードは、PHP コマンドがいつ、どこで実行できるかを決定します。設定できます。マニュアルの各指示には、それが属するモードがあります。たとえば、一部のコマンドは ini_set() を使用して PHP スクリプトで設定できますが、その他のコマンドは php.ini または httpd.conf でのみ設定できます。

たとえば、output_buffering ディレクティブは

PHP_INI_PERDIR に属しているため、ini_set() で設定することはできません。ただし、display_errors ディレクティブは PHP_INI_ALL に属しており、ini_set() を含むどこにでも設定できます。

#モード##PHP_INI_USERPHP_INI_PERDIRPHP_INI_SYSTEMPHP_INI_ALL
意味
ユーザー スクリプト (例: ini_set()) または Windows レジストリ (PHP 5.3 以降) および .user.ini で設定できます
php.ini、.htaccess、または httpd.conf で設定できます
で設定できますphp .ini または httpd.conf set
どこにでも設定できます##

on_modify: 配置修改函数

三、max_input_time、max_execution_time

因为max_input_timemax_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_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进程接收到SIGINTSIGTERMSIGQUITSIGUSR2这些信号时,会调用fpm_pctl()来进行处理。

首先master进程会根据 接收到的信号 和 当前fpm的运行状态 来决定发送给worker进程的是SIGQUIT还是SIGTERM信号,同时注册时间为process_control_timeout的定时事件。

如果在process_control_timeout时间内子进程没有退出,那么master进程会升级SIGQUITSIGTERMSIGTERMSIGKILL,并注册1s的定时事件。SIGKILL就直接终止worker进程了,SIGTERM还能再给worker进程1s的时间。

综上,process_control_timeout可以理解为master进程留给worker进程结束自己的时间,要是到时间worker还没搞定那就开始master自己的策略了。

五、request_terminate_timeout、request_slowlog_timeout

因为request_terminate_timeoutrequest_slowlog_timeout 联系比较密切,所以放在一起来讲。

php-fpm.conf 説明

request_terminate_timeout

; ワーカー プロセスが強制終了されるまでの 1 つのリクエストを処理するためのタイムアウトです。このオプションは次のように指定する必要があります。 'max_execution_time' ini オプション
; が何らかの理由でスクリプトの実行を停止しない場合に使用されます。値 '0' は 'オフ' を意味します。
; 使用可能な単位: s(秒)(デフォルト)、m(分)、h(ours)、または d(ays)
; デフォルト値: 0

翻訳: リクエストを実行するためのタイムアウト期間。その後、ワーカー プロセスは終了します。このオプションは、

max_execution_time this ini オプションが何らかの理由でスクリプトの実行を停止できない場合に使用する必要があります。

request_slowlog_timeout

; 単一リクエストを処理するためのタイムアウト。その後、PHP バックトレースが

; 'slowlog' ファイルにダンプされます。値 '0s' は 'オフ' を意味します。 .
; 使用可能な単位: s(秒)(デフォルト)、m(分)、h(ours)、または d(ays)
; デフォルト値: 0

翻訳: リクエストを実行します。タイムアウトになり、その後 PHP バックトレースがスローログ ファイルに出力されます。

分析

request_slowlog_timeoutrequest_terminate_timeout は、マスター プロセスのハートビート検出 (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
  • ##3 番目のルールは、slowlog が通常のリクエストに影響を及ぼさないようにすることです。

    heartbeat
  • にはタイムアウト時間の 1 つがかかります。 /3 は、各ハートビート検出がすべてのワーカー プロセスを横断する必要があるため、頻繁すぎるハートビート検出を避けるためのものです。

タイムアウト イベントが発生すると、ワーカー プロセスは直接強制終了され (kill(child_pid, SIGTERM);)、カーネルはリソースをリサイクルして client_socket を閉じ、nginx は次の処理を返します。ブラウザに 502 エラーが送信されます。

推奨学習: 「PHP ビデオ チュートリアル

以上がPHP 構成ファイル内のいくつかのタイムアウト構成の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はsegmentfaultで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境