日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

php里面的耗时操作,PHP执行时间那点事

發(fā)布時(shí)間:2024/9/3 php 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php里面的耗时操作,PHP执行时间那点事 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說起php的執(zhí)行時(shí)間,相信每一個(gè)phper都遇到過這方面的問題,特別是在CGI模式下,一般我們都會(huì)通過修改max_execution_time或者在代碼開頭添加set_time_limit(0)來解決問題,但下面這個(gè)場(chǎng)景大家可能也曾經(jīng)遇到過:

我們先將php.ini的執(zhí)行時(shí)間設(shè)置為60S

max_execution_time = 60

再在代碼的開頭設(shè)置執(zhí)行時(shí)間為60S,讓兩者統(tǒng)一

然后運(yùn)行sleep讓程序模擬運(yùn)行20S:

set_time_limit(60);

sleep(20);

echo 1;

會(huì)發(fā)現(xiàn)程序在執(zhí)行到第16S的時(shí)候就報(bào)出了502 Bad Gateway

說好的可以執(zhí)行60S呢?江湖規(guī)矩報(bào)錯(cuò)先翻看日志,查看php-fpm.log,可以發(fā)現(xiàn)有這么一段信息

[06-Dec-2019 12:44:13] WARNING: [pool www] child 19910, script '/home/wwwroot/public/index.php' (request: "GET /index.php") execution timed out (16.120721 sec), terminating

[06-Dec-2019 12:44:13] WARNING: [pool www] child 19910 exited on signal 15 (SIGTERM) after 2573.443300 seconds from start

[06-Dec-2019 12:44:13] NOTICE: [pool www] child 21861 started

這三行日志分別告訴了我們?nèi)齻€(gè)信息

1.子進(jìn)程19910的執(zhí)行時(shí)間超過了16S被終結(jié)了

2.子進(jìn)程19910在啟動(dòng)了2573.44S后被關(guān)閉了

3.子進(jìn)程19910在關(guān)閉后的同一秒子進(jìn)程child 21861被fork出來開始運(yùn)行

也就是說,PHP-CGI在執(zhí)行的過程中,除去我們之前已經(jīng)設(shè)置好的兩個(gè)參數(shù),應(yīng)該還有另外一個(gè)參數(shù)限制了這個(gè)進(jìn)程的執(zhí)行時(shí)間,打開php目錄下的php-fpm.conf看看有無異常

...

pm.min_spare_servers = 16

pm.max_spare_servers = 60

request_terminate_timeout = 15

request_slowlog_timeout = 0

slowlog = var/log/slow.log

...

可以看到有一個(gè)參數(shù)request_terminate_timeout = 15 和我們的超時(shí)閾值非常接近,翻看注釋找到關(guān)于這個(gè)參數(shù)的解釋:

; 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'.

大概的意思是這個(gè)參數(shù)的設(shè)置是當(dāng)max_execution_time啟用時(shí),為了防止php子進(jìn)程因?yàn)槟承┰驘o法停止運(yùn)行而設(shè)置的一個(gè)保護(hù)措施,當(dāng)然這個(gè)保護(hù)措施比較簡(jiǎn)單粗暴,就是直接kill超時(shí)的子進(jìn)程,然后直接fork一個(gè)新的

結(jié)合解釋,我們就很好理解前面日志中出現(xiàn)的三條信息了:因?yàn)閳?zhí)行時(shí)間超過了max_execution_time設(shè)置的閾值,子進(jìn)程19910被直接kill了,然后又生成了一個(gè)新的子進(jìn)程21861

于是我們將php-fpm.conf中的request_terminate_timeout改為30,重啟php,再次執(zhí)行之前的代碼,不再報(bào)502了

看到這里,可能會(huì)有小伙伴會(huì)說,PHP的執(zhí)行執(zhí)行時(shí)間影響的參數(shù)有點(diǎn)多,真的記不住應(yīng)該改那個(gè)才真正的有效,我們不妨從php運(yùn)行的架構(gòu)來梳理一下,不太清楚php運(yùn)行架構(gòu)的小伙伴可以看看我之前寫的《淺析PHP-FPM、CGI、Fast CGI的關(guān)系》

PHP-FPM的程序架構(gòu)是由一個(gè)master進(jìn)程來進(jìn)行管理一個(gè)PHP-CGI的子進(jìn)程池,當(dāng)一個(gè)請(qǐng)求由master進(jìn)程轉(zhuǎn)發(fā)到worker時(shí),master進(jìn)程便會(huì)開始計(jì)時(shí),當(dāng)超過設(shè)定的執(zhí)行時(shí)間時(shí)master進(jìn)程,便會(huì)直接kill掉超時(shí)的worker進(jìn)程(程序的世界也不好混),而我們?cè)O(shè)置max_execution_time設(shè)置的時(shí)間是對(duì)于workder進(jìn)程而言的,所以無論單個(gè)worker進(jìn)程的執(zhí)行時(shí)間設(shè)置多少,都不得超過fpm中的request_terminate_timeout,否則一律kill

文末,再補(bǔ)充兩條在翻看手冊(cè)時(shí)翻到的知識(shí)點(diǎn):

在代碼中使用set_time_limit()會(huì)從零開始重新啟動(dòng)超時(shí)計(jì)數(shù)器

換句話說,如果超時(shí)默認(rèn)是30秒,在腳本運(yùn)行了了25秒時(shí)調(diào)用 set_time_limit(20),那么,腳本在超時(shí)之前可運(yùn)行總時(shí)間為45秒。

這個(gè)相對(duì)簡(jiǎn)單,就不上測(cè)試代碼了,大家有空可以驗(yàn)證一下

set_time_limit()函數(shù)和配置指令max_execution_time只影響腳本本身執(zhí)行的時(shí)間

其他發(fā)生在諸如使用system()的系統(tǒng)調(diào)用,流操作,數(shù)據(jù)庫操作等的腳本執(zhí)行的最大時(shí)間不包括其中。也就是說,比如sleep或者file_get_contents等操作消耗的時(shí)間是不會(huì)計(jì)入max_execution_time的超時(shí)時(shí)間中的

所以其實(shí)我前文寫的代碼即使把sleep設(shè)置為999也不會(huì)報(bào)執(zhí)行超時(shí)的錯(cuò)誤

,用代碼驗(yàn)證下:

set_time_limit(10);

sleep(20);

可以發(fā)現(xiàn)程序確實(shí)沒有報(bào)超時(shí)的錯(cuò)誤,接著我們?cè)倬帉懸欢未a,讓php執(zhí)行非系統(tǒng)調(diào)用和數(shù)據(jù)流等操作的耗時(shí)任務(wù)

set_time_limit(10); //將計(jì)數(shù)器清零,允許執(zhí)行時(shí)間為10S

sleep(10);

$json[] = str_repeat("123456789,",10000); //生成一個(gè)內(nèi)容量較大的數(shù)組

$count = 1000000;

//循環(huán)執(zhí)行1000000次數(shù)據(jù),json_encode和json_decode在對(duì)于長字符串的轉(zhuǎn)化效率不高,所以比較耗時(shí)

while ($count--){

$string = json_encode($json);

json_decode($string,true);

}

結(jié)果如上圖,程序一共執(zhí)行了20S,其中有10S是在sleep也就是系統(tǒng)調(diào)用不算入執(zhí)行超時(shí)時(shí)間,另外10s執(zhí)行的是一段cpu密集型的操作,符合算入max_execution_time超時(shí)時(shí)間的要求,于是符合條件拋出錯(cuò)誤

文末總結(jié):有空可以多翻翻手冊(cè),每天都有新發(fā)現(xiàn)

總結(jié)

以上是生活随笔為你收集整理的php里面的耗时操作,PHP执行时间那点事的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。