淺析php curl_multi_*系列函數進行批量http請求


何起:

  一系列 數量很大 數據不熱 還希望被蜘蛛大量抓取的頁面,在蜘蛛抓取高峰時,響應時間會被拉得很高。

  前人做了這樣一個事兒:頁面分3塊,用3個內部接口提供,入口文件用curl_multi_*系列函數抓取3個內部接口的內容,拼成一個頁面。

  懷疑這樣做會有影響性能的可能。

 

  故學而分析之。

 

看了php官方手冊,總結批量調用過程如下:

  curl_multi_init — 返回一個新cURL批處理句柄,作為curl_init生成的單個curl句柄的容器

  curl_multi_add_handle — 向curl批處理會話中添加單獨的curl句柄。

  curl_multi_exec — 運行當前 cURL 句柄的子連接,curl_multi_select()的值

    curl_multi_select — 等待所有cURL批處理中的活動連接

  curl_multi_getcontent — 如果設置了CURLOPT_RETURNTRANSFER,則返回獲取的輸出的文本流

  curl_multi_remove_handle — 移除curl批處理句柄資源中的某個句柄資源

  curl_multi_close — 關閉一組cURL句柄

摘一段php官網的示例代碼:  

<?php
// 創建一對cURL資源
$ch1 = curl_init();
$ch2 = curl_init();

// 設置URL和相應的選項
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);

// 創建批處理cURL句柄
$mh = curl_multi_init();

// 增加2個句柄
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$active = null;
// 執行批處理句柄
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

// 讀取數據
$content1 = curl_multi_getcontent($ch1);
$content2 = curl_multi_getcontent($ch2);
// 關閉全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

?>

 

疑惑和思考:

  1.批量請求的原理

    php沒有多線程,借助操作系統的多線程來實現(網上看到的)

  2.批量請求以操作系統的多線程機制為基礎,理論上會大量消耗機器的cpu

    a.開發機上驗證,大批量請求時,cpu調用確實會急劇升高

    b.對比 線上前端機的負載情況 和 頁面響應時間拉長 的時間點,發現線上前端機負載並無明顯升高(維持在0.3左右)

    c.網上看到有人在curl_multi_select()返回值不是-1的時候(表示有請求沒有處理完成)usleep(100),休眠以避免不對讀處理狀態而造成的不必要cpu壓力。

  notice:

    2中的a、b有所矛盾,暫未找到根本原因

    2中的c沒有經過實踐測試

 

歡迎閱者批評指正

 

筆者:一般的小帥

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM