在進行大規模的HTTP 請求時,PHP 的cURL 庫是一個非常強大的工具,可以幫助我們進行並發請求,提升性能。然而,簡單地發起多個請求並不一定能夠獲得最佳的性能,因為我們需要有效地管理連接。為了實現更高效的連接優化,可以利用curl_upkeep()和curl_multi_select()這兩個函數來減少連接的開銷。
curl_upkeep() :此函數主要用於管理已初始化的cURL 連接,確保它們在使用時保持有效,並且可以通過保持連接的複用來節省資源,減少重複的連接建立過程。
curl_multi_select() :此函數配合curl_multi_exec()使用,可以幫助我們優化多任務cURL 請求的執行效率。它的作用是阻塞式地等待至少一個cURL 句柄準備好,適合高效地管理大量並發請求。
通過這兩個函數的結合使用,可以大大減少每次請求時的延遲,提高多個請求之間的並發處理效率。
在介紹如何使用curl_upkeep()和curl_multi_select()之前,我們先來回顧一下如何進行基本的多任務處理。下面的代碼演示瞭如何使用curl_multi_init()和curl_multi_exec()來進行並發請求。
// 初始化多個cURL句柄
$mh = curl_multi_init();
$handles = [];
$urls = [
'https://m66.net/api/data1',
'https://m66.net/api/data2',
'https://m66.net/api/data3'
];
// 為每個請求創建一個cURL句柄
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
// 執行多任務請求
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh); // 阻塞直到有活動的請求
}
} while ($active);
// 處理結果並清理
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response;
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
這段代碼通過curl_multi_exec()進行多任務請求,並在每次循環時調用curl_multi_select()等待活動連接,從而避免了不必要的CPU 資源佔用。
為了避免頻繁建立和銷毀連接,我們可以通過curl_upkeep()函數實現連接復用。雖然PHP 並沒有直接提供curl_upkeep()這個函數,但我們可以使用curl_multi_*函數組合實現類似的功能。具體來說,我們會使用一個持久連接池來管理這些連接,而不是每次請求都重新創建連接。
連接池初始化:我們先創建一個cURL 句柄池,池中的連接將被重複利用,而不是每個請求都初始化新的連接。
連接復用:在多任務請求執行期間,我們可以檢查連接池中的連接,若有空閒的連接,可以復用它。
// 創建持久連接池
$mh = curl_multi_init();
$handles = [];
$connectionPool = [];
// 請求的URLs
$urls = [
'https://m66.net/api/data1',
'https://m66.net/api/data2',
'https://m66.net/api/data3'
];
// 初始化cURL句柄並存儲
foreach ($urls as $url) {
if (empty($connectionPool[$url])) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$connectionPool[$url] = $ch; // 將新連接存入連接池
} else {
$ch = $connectionPool[$url]; // 使用連接池中的已有連接
}
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
// 執行多任務請求
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh); // 阻塞直到有活動的請求
}
} while ($active);
// 處理結果並清理
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response;
curl_multi_remove_handle($mh, $ch);
// 這裡我們不關閉連接,保持連接池中的複用
}
curl_multi_close($mh);
在上述代碼中,我們創建了一個簡單的連接池connectionPool ,並在多任務請求執行時使用池中的連接進行複用。這樣可以顯著提高連接效率,尤其是在多個請求指向相同域名時。
通過結合使用curl_upkeep() (連接池管理)和curl_multi_select() (阻塞等待有活動請求),我們可以優化PHP 中的cURL 多任務請求,從而提高系統的整體性能。連接池機制有效減少了連接的頻繁創建和銷毀,節省了系統資源,而curl_multi_select()則保證了高效的並發執行。
使用這種方式,您可以在處理大量HTTP 請求時更高效地管理連接,提高程序的響應速度,減少等待時間,實現更高的性能。