現在の位置: ホーム> 最新記事一覧> ループでcurl_multi_remove_handleを頻繁に呼び出すためのパフォーマンス最適化手法は何ですか?

ループでcurl_multi_remove_handleを頻繁に呼び出すためのパフォーマンス最適化手法は何ですか?

gitbox 2025-06-08

1。Curl_multi_remove_handleどのように機能するかを理解してください

PHPでは、 curl_multi_*一連の関数は、通常、 curl_multi_add_handleおよびcurl_multi_execと併用される非同期的に同時リクエストに能力を提供します。 curl_multi_add_handleを使用して複数のcurlハンドルをマルチハンドルに追加すると、 curl_multi_remove_handleは、リクエストが完了した後、各ハンドルから各ハンドルをマルチハンドルから削除できます。

 $multiCurl = curl_multi_init();
$curlHandles = [];

// 複数を追加しますcurlハンドルmultiハンドルに
for ($i = 0; $i < 5; $i++) {
    $curlHandles[$i] = curl_init("http://gitbox.net/api/data$i");
    curl_multi_add_handle($multiCurl, $curlHandles[$i]);
}

// リクエストを実行します
do {
    $status = curl_multi_exec($multiCurl, $active);
} while ($active);

// 各ハンドルを取り外します
foreach ($curlHandles as $ch) {
    curl_multi_remove_handle($multiCurl, $ch);
    curl_close($ch);
}

curl_multi_close($multiCurl);

上記のコードでは、 curl_multi_remove_handleを介して各curlハンドルを削除します。リソースが正しくリリースされることを保証しますが、ループ内のcurl_multi_remove_handleへの頻繁な呼び出しは、特にリクエストの数が多い場合は、パフォーマンスオーバーヘッドが発生する可能性があります。


2. curl_multi_remove_handleへの頻繁な呼び出しがパフォーマンスに影響するのはなぜですか?

curl_multi_remove_handleを呼び出すとき、PHPは下部のマルチハンドルの状態を更新する必要があります。これは、特に同時リクエストの数が多い場合、比較的時間がかかる操作です。各リクエストが完了すると、ハンドルが削除されると、PHPはマルチスレッドのステータス情報を処理および更新する必要があります。ハンドルを頻繁に削除すると、次のパフォーマンスの問題が発生する可能性があります。

  • 頻繁なメモリ管理:ハンドルを削除するとき、基礎となるメモリ管理メカニズムはリソースを再配分する必要があり、その結果、メモリの割り当てとリリースのオーバーヘッドが得られます。

  • ロックとスレッドの同期curl_multi_remove_handleには、並行して要求するときにスレッドロック操作が含まれます。頻繁に電話がかかる可能性があり、競争のロックにつながり、実行効率をさらに低下させる可能性があります。

  • コールスタックの複雑さ:各コールは、特に高い並行性でスタックの深さを増加させます。ここでは、コールスタックの増加が全体的なパフォーマンスに影響を与える可能性があります。

したがって、これらの操作を最適化することは、特に頻繁な同時リクエストが必要な場合、パフォーマンスを改善するために非常に重要です。


3。パフォーマンス最適化スキル

3.1。ハンドルのバッチ削除

各リクエストが完了した直後にcurl_multi_remove_handleを呼び出す代わりに、すべてのリクエストが完了した後、ハンドルを均一に削除できます。これにより、頻繁にリソースの更新を回避し、パフォーマンスの損失を減らすことができます。

 $multiCurl = curl_multi_init();
$curlHandles = [];

// 複数を追加しますcurlハンドル
for ($i = 0; $i < 5; $i++) {
    $curlHandles[$i] = curl_init("http://gitbox.net/api/data$i");
    curl_multi_add_handle($multiCurl, $curlHandles[$i]);
}

// 同時リクエストを実行します
do {
    $status = curl_multi_exec($multiCurl, $active);
} while ($active);

// 统一移除所有ハンドル
foreach ($curlHandles as $ch) {
    curl_multi_remove_handle($multiCurl, $ch);
    curl_close($ch);
}

curl_multi_close($multiCurl);

すべての要求が完了した後、ハンドルを均一に削除することにより、不必要な中間操作を削減し、パフォーマンスを改善できます。

3.2。 curl_multi_remove_handleへの呼び出し数を減らします

いくつかのシナリオでは、同時リクエストの数を調整することにより、 curl_multi_remove_handleへの呼び出し数を減らすことができます。たとえば、すべてのリクエストのバッチ処理を行い、バッチの完了に応じてハンドルを均一に削除します。

 $multiCurl = curl_multi_init();
$curlHandles = [];

// 1つの処理を想定します10リクエスト
$batchSize = 10;

for ($i = 0; $i < 100; $i++) {
    $curlHandles[$i] = curl_init("http://gitbox.net/api/data$i");
    curl_multi_add_handle($multiCurl, $curlHandles[$i]);
    
    if (count($curlHandles) == $batchSize) {
        // 同時リクエストを実行します
        do {
            $status = curl_multi_exec($multiCurl, $active);
        } while ($active);

        // 统一移除当前批次的所有ハンドル
        foreach ($curlHandles as $ch) {
            curl_multi_remove_handle($multiCurl, $ch);
            curl_close($ch);
        }

        // 清空当前批次的ハンドル数组
        $curlHandles = [];
    }
}

// まだリクエストが残っている場合,処理を続けます
if (count($curlHandles) > 0) {
    do {
        $status = curl_multi_exec($multiCurl, $active);
    } while ($active);

    // 统一移除剩余ハンドル
    foreach ($curlHandles as $ch) {
        curl_multi_remove_handle($multiCurl, $ch);
        curl_close($ch);
    }
}

curl_multi_close($multiCurl);

リクエストのバッチ処理により、 curl_multi_remove_handleの呼び出し数を大幅に削減し、それによりパフォーマンスを向上させることができます。

3.3。永続的な接続を使用します

場合によっては、同じAPI呼び出しを頻繁に行う場合は、HTTPの永続的な接続を有効にすることを検討する場合があります(Keep-Alive)。これにより、Curlは毎回新しい接続を確立するのではなく、同じ接続で複数回リクエストし、 curl_multi_remove_handleへの多くの接続と頻繁な呼び出しを減らします。

curlopt_forbid_reuseをtrueに設定して、各リクエストに新しい接続が使用されるようにすることにより、接続の再利用を無効にできます。接続の多重化を維持すると、通常、特別なニーズなしでパフォーマンスが向上します。

 curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Connection: keep-alive',
]);

接続を持続させることにより、接続の作成と破壊の頻度が減少し、パフォーマンスが向上します。

3.4。カールバッチインターフェイスを使用したネイティブ最適化

リクエストボリュームが非常に大きい場合、PHPカールが最良の選択ではない場合があります。この場合、 Guzzleなどの最新のHTTPクライアントを使用するなど、より高度な同時リクエストメソッドの使用を検討してください。通常、非常に同時リクエストを処理するときにパフォーマンスとメモリ管理が向上します。