web-dev-qa-db-ja.com

同じカールハンドルを再利用します。パフォーマンスが大幅に向上しましたか?

PHPスクリプトでは、さまざまなURLに対してさまざまなcUrl GETリクエスト(100)を実行しています。

Curl_initから同じcurlハンドルを再利用すると、パフォーマンスが向上しますか、それともcURLリクエストの応答時間と比較して無視できますか?

現在のアーキテクチャでは同じcUrlハンドルを維持するのは容易ではないので、私はそれを尋ねています。

おかげで、

ベンジャミン

31
benjisail

URLが同じサーバー上にあるかどうかによって異なります。そうである場合、同じサーバーへの同時要求は接続を再利用します。 CURLOPT_FORBID_REUSEを参照してください。

URLが同じサーバーにある場合は、デフォルトの接続キャッシュが10または20の接続に制限されているため、URLをソートする必要があります。

それらが異なるサーバー上にある場合、同じハンドルを使用しても速度上の利点はありません。

Curl_multi_execを使用すると、異なるサーバーに同時に接続できます(並列)。それでも、数千の同時接続を使用しないようにするには、いくつかのキューイングが必要です。

cURLを閉じる必要があるかどうか からのクロスポストここでも関連があると思うので。

リクエストごとに新しいハンドルを使用し、次のコードで同じハンドルを使用して、curlをベンチマークしてみました。

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
for ($i = 0; $i < 100; ++$i) {
    $Rand = Rand();
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $Rand);
    curl_exec($ch);
    curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
for ($i = 0; $i < 100; ++$i) {
    $Rand = Rand();
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $Rand);
    curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';

そして、次の結果を得た:

ハンドルの再利用なしのカール:8.5690529346466
ハンドルを再利用したカール:5.3703031539917

そのため、実際には同じハンドルを再利用すると、同じサーバーに複数回接続したときにパフォーマンスが大幅に向上します。別のサーバーに接続してみました:

$url_arr = array(
    'http://www.google.com/',
    'http://www.bing.com/',
    'http://www.yahoo.com/',
    'http://www.slashdot.org/',
    'http://www.stackoverflow.com/',
    'http://github.com/',
    'http://www.harvard.edu/',
    'http://www.gamefaqs.com/',
    'http://www.mangaupdates.com/',
    'http://www.cnn.com/'
);
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
foreach ($url_arr as $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_exec($ch);
    curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
foreach ($url_arr as $url) {
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';

そして、次の結果を得た:

ハンドルの再利用なしのカール:3.7672290802002
ハンドルを再利用したカール:3.0146431922913

それでもかなりのパフォーマンスの向上があります。

44

データをサーバーに投稿する同様のシナリオがあります。それは100行以下の要求に分割されるため、大量の要求が生成されます。ベンチマークの実行で、12.614行(127リクエストが必要)に加えて、認証と別のハウスキーピングリクエスト(合計129リクエスト)の2つのアプローチを比較しました。

リクエストは、ネットワーク経由でオンサイトではなく、同じ国のサーバーに送信されます。それらはTLS 1.2によって保護されます(ハンドシェイクも犠牲になりますが、HTTPSがますますデフォルトの選択肢になっていることを考えると、これによりシナリオにさらに似たものになる可能性があります)。

cURLの再利用: 1つの_$curlHandle_、つまりcurl_init()を1回実行した後、_CURLOPT_URL_および_CURLOPT_POSTFIELDS_でのみ変更

_Run  1: ~42.92s
Run  3: ~41.52s
Run  4: ~53.17s
Run  5: ~53.93s
Run  6: ~55.51s
Run 11: ~53.59s
Run 12: ~53.76s
Avg: 50,63s / Std.Dev: 5,8s
TCP-Conversations / SSL Handshakes: 5 (Wireshark)
_

cURLの再利用なし:リクエストごとに1つの_curl_init_

_Run  2: ~57.67s
Run  7: ~62.13s
Run  8: ~71.59s
Run  9: ~70.70s
Run 10: ~59.12s
Avg: 64,24s / Std. Dev: 6,5s
TCP-Conversations / SSL Handshakes: 129 (Wireshark)
_

これは最大のデータセットではありませんが、すべての「再利用」実行はすべての「初期」実行よりも高速であると言えます。平均時間は、ほぼ14秒の差を示します。

7
amenthes

リクエストの数に依存します。それぞれをクローズおよび再オープンするためのオーバーヘッドは無視できますが、1,000を実行する場合はどうでしょうか。数秒以上になる可能性があります。

Curl_multi_initが最速の方法だと思います。

全体は、実行する必要がある要求の数によって異なります。

2
Adam Hopkinson

これもチェック

 
試行{
 $ pool = new HttpRequestPool(
 new HttpRequest($ q1)、
 new HttpRequest($ qn)
); 
 $ pool-> send(); 
 
 foreach($ pool as $ request){
 
 $ out [] = $ request-> getResponseBody(); 
 
} 
} catch(HttpException $ e){
 echo $ e; 
} 
 
 
1
sathia