[xParser] 1.8.0 Вспомогательный Node JS демон или ускоряем парсинг в 27 раз!

Встала задача ускорить, насколько это возможно, работу парсера, т.к. у клиента отработка задания на парсинг 7к ресурсов длилась в течение ~2-3 суток!
Первым делом я подумал, что проблема таится в получении данных со стороннего ресурса. 7 тысяч запросов к стороннему ресурсу только за текстовой информацией, а ещё у каждой записи по 5 картинок, в общей сложности получается 42к запросов к стороннему ресурсу.
Если в среднем запрос длится по 1 секунде, то получается 42 тысячи секунд, что эквивалентно 11 часам и ещё 40 минутам! А ведь ресурс ещё нужно сохранить, на что в среднем уходит по 1-2 секунды. Это ещё +22 часа работы. Итого ~34 часа на отработку задания на парсинг 7к ресурсов, в лучшем случае. Мда… не дело!
А как же встроенная асинхронность?
Помнится, с версии 1.6.0 у компонента появилась классная функция асинхронных запросов к стороннему ресурсу через библиотеку ReactPHP. На деле оказалось, что не на всех серверах оно работает корректно — где-то вообще не работает, а где-то часть запросов теряется.
К сожалению, могу констатировать, что ReactPHP, который был встроен в xParser, не добавляет стабильной асинхронности при запросах к внешнему ресурсу. Поэтому, в будущих версиях он будет либо заменён на что-то другое, либо вообще удалён из компонента. Пока в новых версиях этот функционал принудительно отключён, но сегодня не об этом.
Ищем решение
Поразмышляв, я пришёл к выводу, что компоненту не хватает реальной асинхронности, которая есть, например, в JavaScript. Такие размышления навели меня на мысль: «А что если у компонента будет свой Node JS демон, который будет выполнять запросы к сторонним ресурсам?», идея мне показалась интересной и я принялся её воплощать.
Первое препятствие
Когда всё было готово и тестовый запуск произведён, оказалось, что запросы к сторонним ресурсам — не единственная проблема. Когда парсер собрал все данные и выгрузил картинки к себе, он переходит к сохранению ресурсов через стандартный процессор MODX (resource/create или resource/update). Путём наблюдения за этим процессом было выяснено, что первые ресурсы сохраняются за пол секунды, а то и меньше, но чем дальше в лес, тем дольше времени надо на это действие. Доходит до того, что 1 ресурс где-то на ~1.500 обработанных записей, обновляется через стандартный процессор в течение 40 секунд! С чем это связано, я так и не разобрался (хоть и пытался), может какая утечка памяти или что-то в этом роде…
Прокачиваем демон
Решено было отдать демону и сохранение ресурса. Написав необходимый функционал на стороне Node JS и доработав xParser таким образом, чтобы при доступности демона он отдавал все необходимые данные ему, мы снова принялись тестировать скорость работы парсинга. Результат удивил даже меня. Очень удивил!
Приятный итог
В общем, не буду томить, то же задание на 7к записей отработало за 1 час 15 минут. Мне сначала показалось, что произошёл какой-то сбой и я полез проверять целостность спарсенных данных, оказалось, что всё на месте! Поэтому, если взять изначальные 34 часа, которые по нашим подсчётам требовались на парсинг этого задания и разделить их на итоговый результат, то получается, что работа парсера на этом задании была ускорена в ~27 раз!
P.S.
Я скоро дополню документацию компонента разделом о том, как любой обладатель xParser сможет запустить на своём сервере вспомогательный демон и настроить его. А пока я озабочен безопасностью этого решения.
Комментарии: 20
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Пару лет назад, писал парсер на php который должен был собирать данные и создавать/обновлять ресурс. Изначально нужно было парсить чуть меньше 500 позиций. Затем требования увеличились до 1,5-2к, через пару месяцев 5-7к. Соответственно время парсинга увеличилось в разы. Клиенты компании на которую я работаю, утверждали, что ваш modx говно, решение тоже говно, и мол на битриксе есть готовое решение которое делает это за 20-30 минут. В начале я думал, что просто я не компетентен и упускаю какую-то очень важную деталь, но все оказалось куда проще. Клиенты наглые врунишки!
В итоге тоже пришлось родить монстра на nodejs+php. На текущий день нода обрабатывает порядка от 60к до 80к позиций от разных источников. Начиная от парсинга xml фидов, до работ с api сторонних сервисов. Нода отрабатывает все это дело от 8 до 20 минут (там есть еще пару факторов). В итоге получаем файлик с позициями которые нужно создать/обновить/удалить, этот файлик отрабатывает php, примерно от 10 до 80 минут. Такая разница возникает из-за того, что количество обновляемых/создаваемых ресурсов всегда разная, это может быть как 1к так и 10-15к. Но в среднем 3-3,5к на создание/обновление и 800-1500 позиций на удаление. Вот такая вот кулсторибоб)
А битрикс, да! Маркетологам лишь бы продать этот кусок ? поэтому рождаются такие вот легенды.
1. какой версии нужен node
2. как его поставить, на VPS, ubuntu
А можно ли сделать импорт/экспорт HTML/RSS заданий? (очень удобно создать шаблон, и по его примеру уже создавать новые задания, но не удобно дергать Sequel pro чтобы копировать шаблон задания через базу)
запускаю из консоли файлик /core/components/xparser/cron/parser.php
а даже когда сайт на локалке можно через поддержку обращаться? там же даже удалённо толком не зайти в админку, только если через удалённый рабочий стол
А Инстаграм ни кто не парсит? Так что б мимо их api просто по крону?
rapidapi.com/restyler/api/instagram40
Подскажите как решить такую проблему: при обращении парсером к сайту по селектору body — другой вообще не хочет брать пишет вот что:
В чём может быть дело? уже обновил ноду с 10 до 16 — сильно не помогло. Что я делаю не так?