現在の位置: ホーム> 最新記事一覧> curl_multi_closeでリクエストのタイムアウト制御を実装する方法

curl_multi_closeでリクエストのタイムアウト制御を実装する方法

gitbox 2025-05-12

PHPでは、 curl_multi_*一連の関数を使用すると、複数のHTTP要求を同時に送信し、プログラムの実行効率を大幅に改善できます。ただし、多くの人がcurl_multi_closeを使用してマルチレクエストセッションを終了する場合、重要な問題を無視する傾向があります。

タイムアウト時間が合理的に制御されていない場合、リクエストが長期にわたって反応しない場合、アプリケーション全体が立ち往生し、非常に悪いユーザーエクスペリエンスになります。この記事では、例を使用して、 curl_multi_closeを使用するときにタイムアウトコントロールをエレガントに実装する方法を教えます。

基本的なアイデア

実際、 curl_multi_closecurl_multiハンドルを閉じるためにのみ使用され、タイムアウト自体を制御しません。実際のタイムアウトコントロールは、リクエストを実行する段階で発生する必要があります(つまり、 curl_multi_execおよびcurl_multi_select )。

簡単に言えば、タイムアウト制御は以下に依存します。

  • 単一のカールハンドルにタイムアウトを設定します

  • 実行ループの合計時間を記録して判断します

サンプルコード

これが実用的な例です。 https://gitbox.net/api/endpoint1およびhttps://gitbox.net/api/endpoint2を要求する2つのリクエストがあるとします。すべてのリクエストに合計10秒以上かかることはないと思います。

 <?php

// 2つを作成します cURL ハンドル
$ch1 = curl_init('https://gitbox.net/api/endpoint1');
$ch2 = curl_init('https://gitbox.net/api/endpoint2');

// 各リクエストのタイムアウトを個別に設定します(オプション)
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_TIMEOUT, 8); // 1人あたりのほとんどのリクエスト82番
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_TIMEOUT, 8);

// aを作成します cURL 批处理ハンドル
$mh = curl_multi_init();

// 添加ハンドル到批处理ハンドル中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// バッチ処理を実行します
$startTime = microtime(true);
$timeout = 10; // 合計タイムアウト(2番)

do {
    $status = curl_multi_exec($mh, $active);

    // まだアクティブな接続がある場合
    if ($active) {
        // ブロッキングと待機
        $n = curl_multi_select($mh, 1.0);

        // もし select 戻る -1,忙しいのは避けてください
        if ($n === -1) {
            usleep(100000); // 寝る100毫2番
        }
    }

    // タイムアウトかどうかを確認してください
    if ((microtime(true) - $startTime) > $timeout) {
        echo "要求する合計時間は超えています{$timeout}2番,強制中断。\n";
        break;
    }
} while ($active && $status == CURLM_OK);

// 結果を読んでください
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// 关闭ハンドル
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
curl_close($ch1);
curl_close($ch2);

// 結果を印刷します
echo "Response 1: " . substr($response1, 0, 100) . "...\n";
echo "Response 2: " . substr($response2, 0, 100) . "...\n";
?>

キーポイントの概要

  1. curlopt_timeout単一のリクエストのタイムアウトを制御します。

  2. MicroTime(True)を記録することにより、総実行時間は手動で制御されます。

  3. curl_multi_selectを使用する場合、過度のCPU使用を避けるために、適切なタイムアウト値(1秒など)を設定します。

  4. curl_multi_closeはリソースのクリーニングのみを担当し、タイムアウトロジックを制御しません

注意すべきこと

  • SELECT TIMEOT(たとえば、0.01秒)を短すぎると、システムの負荷が増加する可能性があります。

  • curl_multi_selectが-1を返す場合、それは待機するファイル記述子がなく、忙しいループを避けるために適切な睡眠( USLEEP )が必要です。

  • タイムアウトが発生した場合、リソースの漏れを避けるために、未完成のリクエストを積極的にキャンセルすることが最善です。