some image

Parallel Curl, параллельная загрузка и обработка страниц в PHP

Обо всем

Как увеличить производительность тяжелого парсера контента, обрабатывающего несколько запросов в секунду? При такой производительности каждый такт на счету, и очень не хочется тратить время на простой в ожидании загрузки контента, в то время как можно было бы поработать с уже загрузившимся.

Хочу представить вашему вниманию малоизвестную, но очень полезную библиотеку parallelcurl, являющуюся надстройкой над мультипотоковым curl.

https://github.com/petewarden/ParallelCurl

В чем смысл: библиотека предоставляет простой интерфейс callback-функций для одновременной загрузки и обработки веб контента.

Подключаем библиотеку, создаем объект класса:

$parallelcurl = new ParallelCurl(10);

 

Аргумент — число потоков для одновременной загрузки.

Весь механизм работы очень похож на js callback’и.

Стартуем загрузку, можно в цикле:

$parallelcurl->startRequest('http://example.com', 'on_request_done', array('something'));

 

Можно стартовать хоть 1000 запросов одновременно. Они все складываются в очередь. Выполняется, скажем, 10 одновременно. Как только 1 выполнился, сразу же из очереди берется следующий, а для выполнившегося потока стартует callback функция, переданная параметром:

on_request_done($content, 'http://example.com', $ch, array('something));

 

Первый аргумент, который в нее передастся — контент получившейся страницы. Второй — обработанный URL, третий — поток, из которого можно вытаскивать информацию по соединению, и четвертый — массив значений, которые мы передали при вызове.

В основной ветке при этом можно работать как ни в чем ни бывало, никого не дожидаясь, а для того, чтобы дождаться выполнения всех запросов и callback’ов к ним, нужно выполнить:

$parallelcurl->finishAllRequests();

 

Вообще говоря, идея очень простая, и многие реализовывают этот велосипед руками, но всегда приятнее использовать уже готовые и проверенные решения.

Безусловно, многое нужно допилить под свои нужды, но как начальный каркас — очень рекомендую.