摘要:今天跑腳本遇到一個(gè)奇怪的問題,就是請(qǐng)求到后期會(huì)出現(xiàn)程序阻塞卡死,無異常無響應(yīng),一直掛起,腳本也不會(huì)自動(dòng)結(jié)束。設(shè)置允許執(zhí)行的最長秒數(shù)。增加執(zhí)行超時(shí)后的請(qǐng)求設(shè)置函數(shù)。從錯(cuò)誤類型中,看到確實(shí)是有一些請(qǐng)求在秒內(nèi)未能執(zhí)行完畢。
今天跑腳本遇到一個(gè)奇怪的問題,就是cURL請(qǐng)求到后期會(huì)出現(xiàn)程序阻塞卡死,無異常無響應(yīng),一直掛起,腳本也不會(huì)自動(dòng)結(jié)束。跟對(duì)方溝通后說,“哥們兒,是不是你們的程序有問題啊,這邊研發(fā)排查了,說12點(diǎn)30左右沒有收到你們的請(qǐng)求。然后我自己用網(wǎng)上的json工具請(qǐng)求了,一下就通過了”。是不是很尷尬,關(guān)鍵是根本不知道為什么。然后就是不停的嘗試重跑腳本,偶爾有些腳本就跑過了,但好景不長,隨時(shí)都可能出現(xiàn)無效的時(shí)候。一直看,請(qǐng)求一開始都是能正常完成的,越往后執(zhí)行時(shí)間也變得逐漸增長,然后就可能變成死連接。就想到,肯定是cURL發(fā)送的請(qǐng)求有的無響應(yīng)失效了,已經(jīng)成僵尸連接,還一直阻塞腳本,導(dǎo)致資源一直存在,但是并不能繼續(xù)使用。
找了各種資料,還想嘗試寫一個(gè)類似定時(shí)器的定西,如果腳本執(zhí)行超過1分鐘,則強(qiáng)制丟棄掉該cURL鏈接。不知道PHP怎么實(shí)現(xiàn)這樣的需求,還猶豫要不要用go來實(shí)現(xiàn)。涉及到j(luò)son,xml等,用go畢竟沒有PHP方便,就去手冊(cè)閱讀cURL的內(nèi)容,企圖找到一點(diǎn)有用的東西。而且cURL命令行工具是有重試功能的,猜想擴(kuò)展肯定也有。但是該如何配置呢?
看了PHP超時(shí)處理全面總結(jié)這篇文章中的超時(shí),才知道因?yàn)槲业拇a設(shè)置cURL連接選項(xiàng)時(shí)只設(shè)置了連接超時(shí)時(shí)間,并沒有設(shè)置執(zhí)行超時(shí)時(shí)間。觀察通常10秒內(nèi)正常都應(yīng)該返回?cái)?shù)據(jù),我就設(shè)置了超時(shí)和執(zhí)行時(shí)間都是30秒。增加這個(gè)參數(shù)限制后,總算能捕捉到無響應(yīng)的請(qǐng)求了,剩下的就是如何處理在規(guī)定時(shí)間內(nèi)無法返回結(jié)果的資源了。
就是這幾個(gè)參數(shù)沒有了解過,給排查問題浪費(fèi)了整整一個(gè)下午。
/** * CURLOPT_TIMEOUT設(shè)置cURL允許執(zhí)行的最長秒數(shù)。 * CURLOPT_TIMEOUT_MS設(shè)置cURL允許執(zhí)行的最長毫秒數(shù)。(在cURL7.16.2中被加入。從PHP5.2.3起可使用。) * CURLOPT_CONNECTTIMEOUT在發(fā)起連接前等待的時(shí)間,如果設(shè)置為0,則無限等待。 * CURLOPT_CONNECTTIMEOUT_MS嘗試連接等待的時(shí)間,以毫秒為單位。如果設(shè)置為0,則無限等待。在cURL7.16.2中被加入。從PHP5.2.3開始可用。 * CURLOPT_DNS_CACHE_TIMEOUT設(shè)置在內(nèi)存中保存DNS信息的時(shí)間,默認(rèn)為120秒。 */
增加執(zhí)行超時(shí)后的請(qǐng)求設(shè)置函數(shù)。
/** * curl請(qǐng)求 * * @param $url * @param string $postData * @param int $timeout * @return array|mixed * @throws Exception */ protected static function post($url, $postData = "", $timeout = 5) { $ret = array(); $times = 5; do { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HEADER, false); if ($postData != "") { curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 重要, 該處不能丟 curl 執(zhí)行最大秒數(shù) curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $output = curl_exec($ch); if ($errNo = curl_errno($ch)) { error_log("Error [$errNo]: " . curl_error($ch)); } else { $ret = json_decode($output, true); // 解析的結(jié)果集為空時(shí)停止查詢 if (!is_array($ret) && !trim($ret)) { throw new Exception(__METHOD__ . ": cURL調(diào)用失敗, 信息為: " . $output); } unset($output); } curl_close($ch); if (isset($ret[0]) && $ret[0]) { return $ret; } } while ($times--); exit(__METHOD__ . ": cURL請(qǐng)求重試至 {$times} 次后仍無響應(yīng), 執(zhí)行退出"); }
超時(shí)時(shí)的提示信息設(shè)置如:
error_log("Error [$errNo]: " . curl_error($ch));
我設(shè)置的連接時(shí)間和執(zhí)行時(shí)間限制都是30秒。
Error [28]: Operation timed out after 30000 milliseconds with 0 bytes received
可以輸出查看,針對(duì)這種超時(shí),直接丟棄該次連接,重新初始化一次資源請(qǐng)求即可。當(dāng)然這里嘗試重試6次,6次都還無法正常執(zhí)行完畢,就只能在想別的辦法了。雖然最終并不知道為什么會(huì)有連接失效,但是這樣之后,就能保證基本可以完成任務(wù)了。
我執(zhí)行一個(gè)月的跑數(shù)腳本,所有超時(shí)情況就有這么多,幸運(yùn)的是最終都沒能等到重試6次,就請(qǐng)求成功了。從錯(cuò)誤類型中,看到確實(shí)是有一些請(qǐng)求在30秒內(nèi)未能執(zhí)行完畢。
Error [28]: Operation timed out after 30000 milliseconds with 0 bytes received Error [28]: Operation timed out after 30000 milliseconds with 0 bytes received Error [28]: Operation timed out after 30000 milliseconds with 62399 out of 323196 bytes received
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/23251.html
視頻地址 學(xué)徒卡夫 - 卡夫的Mac 03 - Mac下使用Docker配置PHP環(huán)境 https://www.bilibili.com/vide... 安裝 Docker https://www.docker.com/docker... 下載鏡像 # 安裝基礎(chǔ)鏡像 - ubuntu:14.04 # 拉取鏡像(拉取鏡像經(jīng)常會(huì)失敗,嘗試幾次就好了) docker pull ubuntu:14.0...
視頻地址 學(xué)徒卡夫 - 卡夫的Mac 03 - Mac下使用Docker配置PHP環(huán)境 https://www.bilibili.com/vide... 安裝 Docker https://www.docker.com/docker... 下載鏡像 # 安裝基礎(chǔ)鏡像 - ubuntu:14.04 # 拉取鏡像(拉取鏡像經(jīng)常會(huì)失敗,嘗試幾次就好了) docker pull ubuntu:14.0...
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。本程序抓取的是知乎對(duì)外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。本程序抓取的是知乎對(duì)外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。本程序抓取的是知乎對(duì)外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對(duì)爬取的數(shù)據(jù),進(jìn)行了簡(jiǎn)單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
閱讀 2097·2021-10-08 10:21
閱讀 2490·2021-09-29 09:34
閱讀 3506·2021-09-22 15:51
閱讀 4946·2021-09-22 15:46
閱讀 2324·2021-08-09 13:42
閱讀 3447·2019-08-30 15:52
閱讀 2734·2019-08-29 17:13
閱讀 1564·2019-08-29 11:30