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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php-fpm 超时,PHP超时的坑

發布時間:2023/12/4 php 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php-fpm 超时,PHP超时的坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

結合去年國慶和過年期間平臺碰到的一些問題,下面主要介紹的是PHP里面會涉及到的各種超時以及其中存在的坑。

Nginx的超時配置

fastcgi_connct_timeout 60

Nginx和fastcgi進程建立連接的超時時間,默認60秒,如果超過了這個時間就斷開連接。

fastcgi_read_timeout 300

和fastcgi進程建立連接后獲得fastcgi進程響應的超時時間,默認60秒,如果超過了這個時間都沒有獲得響應就斷開連接。我們經常碰到的是'504 Gateway Time-out',就是因為后端連接沒有在超時時間內返回數據導致的。我們經常碰到的是'502 Bad Gateway',是因為fastcig進程報錯,導致連接斷開。

fastcgi_send_timeout 300

Nginx向fastcgi進程發送請求的超時時間,默認60秒,如果超過了這個時間都沒有發送完就斷開連接。可以通過上傳比較大的文件,就會出現超時,然后就會返回'504 Gateway Time-out'。

PHP,PHP-FPM 的超時配置

max_execution_time 300

這個參數是在php.ini中設置的,說實在的這個參數沒有什么太大的意義,因為這個300秒的超時時間僅僅是統計本身代碼的執行時間,不包括網絡請求,系統調用,數據庫查詢,sleep()等的時間,如果超過這個時間會產生一個'Fatal error: Maximum execution time'的錯誤,然后返回的是'500 Internal Server Error'。我們程序大部分的時間都是花在網絡請求,數據庫查詢方面的。

request_terminate_timeout 0

這個參數是在php-fpm中設置的,這個超時時間就是整個fastcgi花費的所有時間,這個和max_execution_time最大的不同,如果總時間超過了,會直接將FPM進程kill掉,然后返回'502 Bad Gateway'。很多人認為配置了這個參數max_execution_time就失效了,實際不是的,先達到哪個的超時時間就哪個配置起作用的。

建議是不要開啟這個參數,因為如果你某個程序超時了,進程直接kill掉,你的數據完整性就沒有辦法保證了,可以在nginx那邊做連接超時的控制和做好程序請求第三方資源超時時間的控制。

接口請求方面的超時設置

這部分要特別注意,在沒有什么并發量的時候沒有什么問題,在并發量大的時候,如果有些對接的第三方系統掛了或是處理速度很慢了,你的FPM進程很快就會用完,然后就是各種502,然后很有可能的就是系統崩潰了。我們在框架層面,對需要用到的請求方法做了統一的封裝。

/**

* CURL 提交請求數據,現在基本的接口都是使用curl進行post請求

*

* @author dwer

* @date 2016-04-11

* @param string $url 請求URL

* @param string $postData 請求發送的數據

* @param int $port 請求端口

* @param int $timeout 超時時間

* @param array $headers 請求頭信息

* @return bool|mixed

*/

function pft_curl_post($url, $postData, $port = 80, $timeout = 25, $headers = []) {

//超時時間處理

$timeout = intval($timeout);

$timeout = $timeout <= 0 ? 25 : $timeout;

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_PORT, $port);

curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HEADER, 0);

if ((is_array($headers) || is_object($headers)) && count($headers)) {

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

}

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

$res = curl_exec($ch);

//錯誤處理

$errCode = curl_errno($ch);

if ($errCode > 0) {

curl_close($ch);

return false;

} else {

//獲取HTTP碼

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($httpCode != 200) {

curl_close($ch);

return false;

} else {

curl_close($ch);

return $res;

}

}

}

file_get_contents的封裝

/**

* 統一封裝的file_get_contents, 原生的file_get_contents絕對不能使用,沒有設置超時時間,如果碰到網絡問題,這個進程會一直卡在那邊,無情地占用你的網絡連接。

* @author dwer

*

* @param string $url 請求url

* @param integer $timeout 超時時間

* @param array $header 請求頭部

* @return

*/

function pft_file_get_contents($url, $timeout = 10, $header = []){

$url = strval($url);

$timeout = intval($timeout);

$timeout = $timeout <= 0 ? 10 : $timeout;

$contextOptions = [

'http' => ['timeout' => $timeout]

];

if($header) {

$contextOptions['http']['header'] = $header;

}

$context = stream_context_create($contextOptions);

$res = file_get_contents($url, false, $context);

return $res;

}

SoapClient的封裝

/**

* 統一封裝的SOAP客戶端封裝,有些系統還在使用soap協議提供接口

* @author dwer

*

* 用法是一樣的,只是添加了設置超時的時間的方法

* $soapClient = new PftSoapClient('xxx.wsdl');

* $soapClient->setTimeout(25);

* $soapClient->getMyMoney($params);

*/

class PftSoapClient extends \SoapClient {

//超時的時間

private $timeout = 0;

//設置超時時間

public function setTimeout($timeout) {

$timeout = intval($timeout);

$timeout = $timeout <= 0 ? 25 : $timeout;

$this->timeout = $timeout;

}

//請求接口

public function __doRequest($request, $location, $action, $version, $oneWay = FALSE) {

if ($this->timeout <= 0) {

//使用默認的方式

$res = parent::__doRequest($request, $location, $action, $version, $oneWay);

} else {

//使用添加了超時的方式

$socketTime = ini_get('default_socket_timeout');

ini_set('default_socket_timeout', $this->timeout);

$res = parent::__doRequest($request, $location, $action, $version, $oneWay);

ini_set('default_socket_timeout', $socketTime);

}

return $res;

}

}

數據庫,Redis方面的超時

在Mysql和Redis服務器的配置中就會設置wait_timeout 和 timeout 參數,保證連接在超時沒有連接的情況下斷開連接。在程序方面需要做的就是處理超時后的'The MySQL server has gone away' 和 'PHP Fatal error: Uncaught exception 'RedisException' with message 'read error on connection'' 的異常捕獲和重連接處理。不過正常情況下,這些在底層框架應該都做了統一的封裝。

總結

以上是生活随笔為你收集整理的php-fpm 超时,PHP超时的坑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。