現在の位置: ホーム> 最新記事一覧> curl_multi_exec()とcurl_share_init()を組み合わせて、同時リクエストの最適化を実現する方法

curl_multi_exec()とcurl_share_init()を組み合わせて、同時リクエストの最適化を実現する方法

M66 2025-05-18

最新のWeb開発では、多数のHTTP要求の処理は、バッチクロールインターフェイスデータ、並列ダウンロードリソース、リンクステータスのチェックなどなど、一般的な要件です。この目的のために、PHPはcurl_multi_*シリーズ関数を提供して同時リクエストを実装しますが、 Curl_share_*シリーズは複数のCurlハンドル間でリソース(DNSキャッシュなど)を共有してパフォーマンスをさらに最適化できます。この記事では、curl_multi_exec()curl_share_init()を組み合わせて、効率的な同時リクエスト最適化を実現する方法を紹介します。

1 ??なぜcurl_multi_*を使用するのですか?

curl_multi_*一連の関数を使用すると、1つのラインで待つのではなく、複数のHTTP要求を同時に送信できます。そのコアワークフローは次のとおりです。

  1. マルチハンドル( curl_multi_init )を初期化します。

  2. 複数の簡単なハンドル( curl_init )をマルチハンドルに追加します。

  3. curl_multi_exec()を使用して、同時リクエストを駆動します。

  4. curl_multi_select()を使用して、アクティブハンドルを待ちます(CPUアイドルを避けます)。

  5. 結果を収集し、リソースを閉じます。

この方法は、クローラー、インターフェース集約、CDN予熱など、同時に処理するために多数のリクエストが必要なシナリオに特に適しています。

2 ?? curl_share_*とは?なぜそれを組み合わせて使用​​するのですか?

curl_multi_*は同時リクエストを送信できますが、たとえば、それぞれの簡単なハンドルはデフォルトで独立しています。たとえば、それぞれがDNSを個別に解決し、独自のCookieを維持する必要があります。Curl_share_ *一連の関数は、複数の簡単なハンドルを使用して特定の内部リソースを共有できます(DNSキャッシュ、SSLセッション、クッキーなどなど、作業を削減できます。

コアステップは次のとおりです。

  1. curl_share_init()を使用して、共有オブジェクトを作成します。

  2. curl_share_setopt()を使用して、共有コンテンツ(curlshopt_shareなど)を設定します。

  3. curl_setopt($ ch、curlopt_share、$ share)を使用して、共有オブジェクトを簡単なハンドルに添付します。

  4. リクエストが完了したら、共有オブジェクトをリリースします。

3 ??完全な例:同時リクエスト +共有DNSキャッシュ

以下は、実際に実行可能なPHPコードの例です。

 <?php

// 同時リクエストが必要ですURLリスト
$urls = [
    'https://m66.net/api/endpoint1',
    'https://m66.net/api/endpoint2',
    'https://m66.net/api/endpoint3',
    'https://m66.net/api/endpoint4'
];

// 初期化 multi handle
$multiHandle = curl_multi_init();

// 共有オブジェクトを作成します
$shareHandle = curl_share_init();
curl_share_setopt($shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);

// それぞれを保存します easy handle
$curlHandles = [];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SHARE, $shareHandle);
    curl_multi_add_handle($multiHandle, $ch);
    $curlHandles[$url] = $ch;
}

// 同時リクエストを実行します
$active = null;
do {
    $mrc = curl_multi_exec($multiHandle, $active);
    if ($mrc == CURLM_CALL_MULTI_PERFORM) {
        continue;
    }
    curl_multi_select($multiHandle);
} while ($active && $mrc == CURLM_OK);

// 結果を収集します
$responses = [];
foreach ($curlHandles as $url => $ch) {
    $responses[$url] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

// 閉鎖 multi handle そして share handle
curl_multi_close($multiHandle);
curl_share_close($shareHandle);

// 結果を印刷します
foreach ($responses as $url => $content) {
    echo "Response from $url:\n";
    echo $content . "\n\n";
}

4 ??最適化のキーポイントの概要

curl_multi_を使用して、並行性パフォーマンスを改善*:複数のリクエストを同時に開始および処理し、合計時間延長を大幅に削減します。
curl_share_を使用して重複したオーバーヘッド *を保存します*:DNSキャッシュなどのリソースを共有することにより、複製の解析を避け、全体的な効率を向上させます。
注リソースリリース:リクエストが完了したら、各簡単なハンドル、マルチハンドル、共有ハンドルをリリースすることを忘れないでください。
curl_multi_select()と組み合わせて:100%のCPU占有率を回避するためのネットワークアクティビティを待ちます。

5 ??適用可能なシナリオ

  • 高い同時インターフェイス集約要求。

  • 多数のページまたはファイルのバルククロール。

  • ウェブサイトの監視と健康チェック。

  • CDNまたはキャッシュウォームアップ。

curl_multi_exec()およびcurl_share_init()を使用すると、真の並行性を達成するだけでなく、リソース共有を通じて重複した作業を削減し、非常に並行したネットワークリクエストを処理するときにPHPをより効率的で安定させます。

実際のアプリケーションで最適化ボトルネックに遭遇した場合、接続プーリング、タスクスケジューリング、例外処理、および全体のソリューションを改善するその他の手段をさらに組み合わせることができます。