何起:
一系列 數量很大 數據不熱 還希望被蜘蛛大量抓取的頁面,在蜘蛛抓取高峰時,響應時間會被拉得很高。
前人做了這樣一個事兒:頁面分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沒有經過實踐測試
歡迎閱者批評指正
筆者:一般的小帥