成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php擴(kuò)展cURL執(zhí)行中途無響應(yīng)

hufeng / 2208人閱讀

摘要:今天跑腳本遇到一個(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

相關(guān)文章

  • PHP開發(fā)環(huán)境01 - Mac下使用Docker配置PHP環(huán)境(只限于學(xué)習(xí))

    視頻地址 學(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...

    gitmilk 評(píng)論0 收藏0
  • PHP開發(fā)環(huán)境01 - Mac下使用Docker配置PHP環(huán)境(只限于學(xué)習(xí))

    視頻地址 學(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...

    baukh789 評(píng)論0 收藏0
  • php爬蟲:知乎用戶數(shù)據(jù)爬取和分析

    摘要:背景說明小拽利用的寫的爬蟲,實(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)代碼...

    Jioby 評(píng)論0 收藏0
  • php爬蟲:知乎用戶數(shù)據(jù)爬取和分析

    摘要:背景說明小拽利用的寫的爬蟲,實(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)代碼...

    honhon 評(píng)論0 收藏0
  • php爬蟲:知乎用戶數(shù)據(jù)爬取和分析

    摘要:背景說明小拽利用的寫的爬蟲,實(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)代碼...

    saucxs 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<