當前位置: 首頁> 最新文章列表> 如何結合curl_multi_select() 和curl_upkeep() 做連接優化

如何結合curl_multi_select() 和curl_upkeep() 做連接優化

M66 2025-06-06

在進行大規模的HTTP 請求時,PHP 的cURL 庫是一個非常強大的工具,可以幫助我們進行並發請求,提升性能。然而,簡單地發起多個請求並不一定能夠獲得最佳的性能,因為我們需要有效地管理連接。為了實現更高效的連接優化,可以利用curl_upkeep()curl_multi_select()這兩個函數來減少連接的開銷。

1. 什麼是curl_upkeep()curl_multi_select()

  • curl_upkeep() :此函數主要用於管理已初始化的cURL 連接,確保它們在使用時保持有效,並且可以通過保持連接的複用來節省資源,減少重複的連接建立過程。

  • curl_multi_select() :此函數配合curl_multi_exec()使用,可以幫助我們優化多任務cURL 請求的執行效率。它的作用是阻塞式地等待至少一個cURL 句柄準備好,適合高效地管理大量並發請求。

通過這兩個函數的結合使用,可以大大減少每次請求時的延遲,提高多個請求之間的並發處理效率。

2. 基本的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 資源佔用。

3. 使用curl_upkeep()實現連接復用

為了避免頻繁建立和銷毀連接,我們可以通過curl_upkeep()函數實現連接復用。雖然PHP 並沒有直接提供curl_upkeep()這個函數,但我們可以使用curl_multi_*函數組合實現類似的功能。具體來說,我們會使用一個持久連接池來管理這些連接,而不是每次請求都重新創建連接。

實現步驟:

  1. 連接池初始化:我們先創建一個cURL 句柄池,池中的連接將被重複利用,而不是每個請求都初始化新的連接。

  2. 連接復用:在多任務請求執行期間,我們可以檢查連接池中的連接,若有空閒的連接,可以復用它。

示例代碼:

 // 創建持久連接池
$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 ,並在多任務請求執行時使用池中的連接進行複用。這樣可以顯著提高連接效率,尤其是在多個請求指向相同域名時。

4. 總結

通過結合使用curl_upkeep() (連接池管理)和curl_multi_select() (阻塞等待有活動請求),我們可以優化PHP 中的cURL 多任務請求,從而提高系統的整體性能。連接池機制有效減少了連接的頻繁創建和銷毀,節省了系統資源,而curl_multi_select()則保證了高效的並發執行。

使用這種方式,您可以在處理大量HTTP 請求時更高效地管理連接,提高程序的響應速度,減少等待時間,實現更高的性能。