<rmcreative>

RSS

rolling-curl

13 мая

rolling-curl — PHP-класс для параллельного выполнения большого количества асинхронных HTTP-запросов при помощи curl, написанная Josh Fraser и поддерживаемая на данный момент мной.

Правильно чистит память, не простаивает зря, выполняя одновременно заданное число запросов. Обрабатывает каждый ответ сразу после выполнения запроса.

Пример:

// URL, которые будем обрабатывать
$urls = array(
  "http://www.google.com",
  "http://www.facebook.com",
  "http://www.yahoo.com",
);
 
// функция для обработки ответа
function request_callback($response, $info) {
  // получаем title страницы
  if (preg_match("~<title>(.*?)</title>~i", $response, $out)) {
    $title = $out[1];
  }
  echo "<b>$title</b><br />";
  print_r($info);
  echo "<hr>";
}
 
$rc = new RollingCurl("request_callback");
// одновременно позволим не более 20 запросов
$rc->window_size = 20;
foreach ($urls as $url) {
    // добавляем запросы в очередь
    $request = new Request($url);
    $rc->add($request);
}
// запускаем
$rc->execute();

Пользуемся

Комментарии

  1. №2528
    mktums
    mktums 13.05.2010 14:41:17

    Спасибо :) Возьму на заметку :)

  2. №2529
    Ewg
    Ewg 13.05.2010 14:43:13

    Как скачать?

  3. №2530
    Максим
    Максим 13.05.2010 17:38:24

    Удобная вешь+ еще и на curl. А по асинхроным серверам на php ничего не завалялось случайно ?

  4. №2531
    Andron
    Andron 13.05.2010 17:56:25

    Спасибо, возможно пригодится :)

  5. №2532
    Sam
    Sam 13.05.2010 18:53:30

    Ewg

    Можно забрать из SVN Google Code.

  6. №2533
    Sam
    Sam 13.05.2010 19:10:35

    Максим

    У меня лично по асинхронным нет, но есть http://github.com/kakserpom/phpdaemon.

  7. №2534
    Сергей
    Сергей 13.05.2010 23:16:25

    Зачем

    $request = new Request($url);

    если можно

    $rc->request($url);

    Вообще довольно странная библиотека...

  8. №2535
    Сергей
    Сергей 14.05.2010 0:07:54

    И правда что-то не так

    Почему то при запуске example.php функции curl_multi_exec и curl_multi_info_read у меня запускались по 94000 с лишним раз.

    Что то там явно не так. Будто цикл какой-то крутится без таймаутов.

    Там вот эта последовательность

      160,3418     527568         -> curl_multi_exec() /home/seriy/rolling-curl-read-only/RollingCurl.php:255
      160,3418     527568         -> curl_multi_info_read() /home/seriy/rolling-curl-read-only/RollingCurl.php:259
      160,3419     527568         -> curl_multi_exec() /home/seriy/rolling-curl-read-only/RollingCurl.php:255
      160,3419     527568         -> curl_multi_info_read() /home/seriy/rolling-curl-read-only/RollingCurl.php:259
      160,3419     527568         -> curl_multi_exec() /home/seriy/rolling-curl-read-only/RollingCurl.php:255
      160,3420     527568         -> curl_multi_info_read() /home/seriy/rolling-curl-read-only/RollingCurl.php:259
      160,3420     527568         -> curl_multi_exec() /home/seriy/rolling-curl-read-only/RollingCurl.php:255
    

    Очень много раз повторяется (по 20-100 тыс раз)

    Я бы не советовал этот класс использовать..

  9. №2536
    Сергей
    Сергей 14.05.2010 1:01:31

    Да и ничуть оно ни асинхронное/неблокирующее.

    Если в example.php в самом конце после $rc->execute(); вставить например print "Hello world"; то если все действительно асинхронно, то сперва напечатается "Hello world" а потом уже все остальное а тут сперва отрабатывает полностью $rc->execute(); (т.е. оно заблокировало все операции) и только потом print

    Так что асинхронностью тут и не пахнет. Многопоточность разве что...

  10. №2537
    Psih
    Psih 14.05.2010 1:40:05

    http://github.com/kakserpom/phpdaemon - ыыы, Данко! Я этого психа знаю лично - он на демонах на PHP собаку съел, целую стаю, стаж у него с этим лет 6-7 точно. Так что это реально хорошее решение будет, от опытного спеца :)

  11. №2538
    Sam
    Sam 14.05.2010 3:02:47

    Сергей

    Слово «асинхронные» тут относится именно к запросам и их обработке, а не к библиотеке в целом.

    Советую почитать про curl_multi_exec и curl_multi_info_read.

  12. №2543
    Сергей
    Сергей 14.05.2010 22:44:17

    Sam

    Ок, насчет асинхронности в целом согласен, хотя к библиотеке в целом это не очень подходит.

    Но то, что там в какой-то момент начинает крутиться цикл по 20-90 тыс итераций это явно проблема.

  13. №2545
    Sam
    Sam 15.05.2010 0:40:20

    Сергей

    Для curl_multi это совершенно нормально и указано в описаниях к методам.

  14. №2547
    Константин
    Константин 15.05.2010 1:25:26

    Спасибо, но не пойму вот чего – я хочу сделать 5 миллионов запросов в 5 потоков. Все 5 миллионов я в $requests, понятное дело, не засуну – память не резиновая. Хотелось бы добавлять запросы в коллбэке по мере их выполнения. Однако приходится дождаться выполнения всех 5 запросов в первом потоке, и затем запускать следующий поток.

    Либо делать множество более коротких очередей – скажем, 5 тысяч раз по 1000 урлов. Что уже лучше, но усложняет логику. Есть выход?

  15. №2553
    Sam
    Sam 16.05.2010 13:49:21

    В самой библиотеке выхода, думаю, нет. Занесите в тикет, надо будет подумать.

  16. №2609
    alexf2000
    alexf2000 02.06.2010 17:01:48

    Может ли один из урлов завесить выполнение всех запросов? Если скажем в списке урлов не яхо, а вася.пупкин.цюрюпинск.херсон.уа и на этом сервере днс сначала 3 минуты думает, а потом не отвечает и до хттп соотсветственно дело даже не доходит или доходит, но сервер выдаёт мегабайтный файл по 1 байту в секунду? :)

  17. №2613
    Sam
    Sam 03.06.2010 12:27:17

    Нет, не может.

  18. №2661
    Jei
    Jei 29.06.2010 17:16:23

    Возникла пара вопросов:

    1) при работе скрипта (параллельно логинишься на два сайта; после этого параллельно забирается контент одной нужной страницы с каждого сайта) процес апача грузит проц на 50%. Это нормально или проблема конкретно у меня? ОС - виндовсХР, пакет - денвер+расширения, $rc->execute() - чтобы залогиниться и куки получить, второй $rc->execute()- чтобы получить контент.

    2) Хотелось бы, чтобы после того как залогинишься на сайте, сразу начинал работать другой запрос для получения контента страницы, и после получения парситься, независимо от запросов к другим сайтам. Такое возможно с данным функционалом?

  19. №2935
    Turbonist
    Turbonist 27.08.2010 0:40:17

    Привет!

    Спасибо за либу. Очень пригодилось.

    Есть вопрос.

    С учетом того, что:

    запросов допустим 1000, а

    $rc->window_size = 20;
    for($i=0;$i<1000;$i++){
    $request = new Request($url . $i);
    $request->options = array(CURLOPT_TIMEOUT => 3);
    $rc->add($request);
    }

    , то либа должна отрабатывать каждые 3 сек минимум 20 запросов. Независимо от скорости получения контента (ибо CURLOPT_TIMEOUT => 3). Значит на всю операцию должно уйти не более 150 сек. Добавим 150 сек для прочих операций. Итого 5 мин. Однако, на деле может и час и два работать. Такое впечатление, что после первых 20 потоков переходит в режим однопоточности + не работает CURLOPT_TIMEOUT.

    С чем может быть связано?

  20. №2937
    Turbonist
    Turbonist 27.08.2010 2:34:21

    в догонку к предыдущему посту

    [total_time] => 35.851
        [namelookup_time] => 0.06
        [connect_time] => 18.847
        [pretransfer_time] => 18.847
        [starttransfer_time] => 35.781

    как-то эти цифры не совместимы с

    $rc->options = array(CURLOPT_TIMEOUT => 5,CURLOPT_CONNECTTIMEOUT => 5);

    версия curl libcurl/7.19.6

    может дело в самой либе curl?

  21. №2910
    Sam
    Sam 27.08.2010 13:02:45

    Jei

    1) Не уверен. У меня не наблюдается.

    2) Да, в коллбэках писать надо.

    Turbonist

    Скорее всего в curl. Параметры либе вроде передаются.

  22. №2943
    Turbonist
    Turbonist 27.08.2010 16:58:37

    Скорее всего в curl. Параметры либе вроде передаются.

    на кодах в вопросах, 12 вопрос, чел тоже испытывает проблемы с тем же самым.

    вообще таймаут - это единственное, что пока не позволяет поменять сокеты на курл.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.