В php-скрипте я делаю много разных запросов cUrl GET (сотни) для разных URL-адресов.
Повторное использование одного и того же ручка curl от curl_init улучшит производительность или это незначительно по сравнению с временем отклика запросов cURL?
Я прошу, потому что в текущей архитектуре было бы непросто сохранить один и тот же дескриптор cUrl.
Благодаря,
Вениамин
Это зависит от того, находятся ли URL-адреса на одном сервере или нет. Если они есть, одновременные запросы на тот же сервер будут повторно использовать соединение. см. CURLOPT_FORBID_REUSE.
Если URL-адреса иногда находятся на одном сервере, вам необходимо отсортировать URL-адреса, поскольку кеш-соединение по умолчанию ограничено десятью или двадцатью соединениями.
Если они находятся на разных серверах, нет преимущества скорости при использовании одного и того же дескриптора.
С curl_multi_exec вы можете одновременно подключаться к различным серверам (параллельно). Даже тогда вам нужно несколько очередей, чтобы не использовать тысячи одновременных подключений.
Crossposted from Я должен закрыть 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>';
и получил следующие результаты:
Curl без повторного использования ручки: 8.5690529346466
Curl с повторным использованием ручки: 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>';
И получил следующий результат:
Curl без повторного использования ручки: 3.7672290802002
Curl с повторным использованием ручки: 3.0146431922913
Все еще довольно существенное увеличение производительности.
У меня есть аналогичный сценарий, когда я отправляю данные на сервер. Он помещается в запросы ~ 100 строк, поэтому он создает много запросов. В контрольном контроле я сравнил два подхода для 12.614 строк (127 запросов) плюс аутентификацию и другой запрос на ведение домашнего хозяйства (всего 129 запросов).
Запросы передаются по сети на сервер в той же стране, а не на месте. Они защищены TLS 1.2 (рукопожатие также принесет свои плоды, но, учитывая, что HTTPS становится все более предпочтительным выбором по умолчанию, это может даже сделать его более похожим на ваш сценарий).
При повторном использовании cURL: один $curlHandle
который является curl_init()
, один раз, а затем изменен только с помощью 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: один 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)
Это не самый большой набор наборов данных, но можно сказать, что все «повторные» тиражи быстрее, чем все «init». Среднее время показывает разницу почти 14 секунд.
Это зависит от того, сколько запросов вы будете делать – накладные расходы на закрытие и повторное открытие каждого из них небрежны, но когда вы делаете тысячу? Может быть несколько секунд или больше.
Я считаю, что curl_multi_init будет самым быстрым методом.
Все зависит от того, сколько запросов вам нужно сделать.
проверьте это тоже
пытаться { $ pool = новый HttpRequestPool ( новый HttpRequest ($ q1), новый HttpRequest ($ qn) ); $ Бассейн-> отправить (); foreach ($ pool as $ request) { $ out [] = $ request-> getResponseBody (); } } catch (HttpException $ e) { echo $ e; }