[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
Если ReactPhp не подходит, то можно глянуть в сторону Swoole www.swoole.co.uk/
По заголовку, ожидал хоть немного кода и пояснения того как автор прикручивал nodejs к xparser, но оказалось, что это скорее анонс. В любом случае, новость хорошая.
Пару лет назад, писал парсер на 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 позиций на удаление. Вот такая вот кулсторибоб)
Пару лет назад, писал парсер на 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 позиций на удаление. Вот такая вот кулсторибоб)
ожидал хоть немного кодаПост в разделе «Новые дополнения и их версии» с префиксом «xParser 1.8.0» в названии. Да, это анонс.
А битрикс, да! Маркетологам лишь бы продать этот кусок ? поэтому рождаются такие вот легенды.
Пост в разделе «Новые дополнения и их версии»Да, не обратил внимания. Прошу прощенья.
на битриксе есть готовое решениеаххаха как же знакомо! А что париться! Покупаете 1с предприятие, потом 1с битрикс связываете одно с другим и продажи прут! Там же все из коробки уже настроено! Осталось только подключить! :))) Я бы взял у Павла гвоздь, и вбил бы его в голову тому гениальному маркетологу.
не поленился залогинититься, чтобы поставить лайк)
Ну что сказать… Не так давно нужно было спарсить несколько тыщ страниц. Использовал стороннее ПО, рекламировать не буду. 7 тыщ парсилось почти сутки. А потом клоудфлэр начал что-то подозревать и запломбировал доступ к сайту. Толи я прокси не так настроил, то ли… В общем, Павел выбора не оставляет — надо брать!
будет ли версий 1.8 работать без серверного node? Не уверен, что он есть у меня на хостинге. И, в догонку, может будет какая-то инструкция:
1. какой версии нужен node
2. как его поставить, на VPS, ubuntu
1. какой версии нужен node
2. как его поставить, на VPS, ubuntu
будет ли версий 1.8 работать без серверного node?Конечно. Демон — это толкьо дополнение по желанию.
Очень круто, потесчу скорость -)
А можно ли сделать импорт/экспорт HTML/RSS заданий? (очень удобно создать шаблон, и по его примеру уже создавать новые задания, но не удобно дергать Sequel pro чтобы копировать шаблон задания через базу)
А можно ли сделать импорт/экспорт HTML/RSS заданий? (очень удобно создать шаблон, и по его примеру уже создавать новые задания, но не удобно дергать Sequel pro чтобы копировать шаблон задания через базу)
А можно ли сделать импорт/экспорт HTML/RSS заданий?Могу добавить в бэклог, однако не обещаю, что скоро появится.
доброго дня! возникает ошибка после обновления, в какую сторону копать?
запускаю из консоли файлик /core/components/xparser/cron/parser.php
запускаю из консоли файлик /core/components/xparser/cron/parser.php
Fatal error: Uncaught InvalidArgumentException: Expecting a DOMNodeList or DOMNode instance, an array, a string, or null, but got "boolean". in /core/components/xparser/vendor/symfony/dom-crawler/Crawler.php:120
Stack trace:
#0 /core/components/xparser/vendor/symfony/dom-crawler/Crawler.php(67): Symfony\Component\DomCrawler\Crawler->add(false)
#1 /core/components/xparser/handlers/domcrawler/xpdomcrawler.class.php(44): Symfony\Component\DomCrawler\Crawler->__construct(false)
#2 /core/components/xparser/handlers/parser/xpparser.class.php(225): xpDomCrawler->factory(false)
#3 /core/components/xparser/handlers/parser/xpparser.class.php(553): xpParser->getSourceItems(Array)
#4 /core/components/xparser/handlers/parser/xpparser.class.php(704): xpParser->parseTask(Array)
#5 /core/components/xparser/processors/mgr/task/parse.class.php(111): xpParser->parseTask(Array)
#6 /core/components/xparser/vendor/symfony/dom-crawler/Crawler.php on line 120
в какую сторону копать?В сторону ТехПоддержки на Модстор, пжл.
запустил по новой — всё ок! даже не знаю в чём могла быть ошибка
а даже когда сайт на локалке можно через поддержку обращаться? там же даже удалённо толком не зайти в админку, только если через удалённый рабочий стол
а даже когда сайт на локалке можно через поддержку обращаться? там же даже удалённо толком не зайти в админку, только если через удалённый рабочий стол
Привет всем
А Инстаграм ни кто не парсит? Так что б мимо их api просто по крону?
А Инстаграм ни кто не парсит? Так что б мимо их api просто по крону?
Я пользуюсь сторонней апишкой, там бесплатно 100 запросов в месяц. Мне хватает.
rapidapi.com/restyler/api/instagram40
rapidapi.com/restyler/api/instagram40
Добрый день.
Подскажите как решить такую проблему: при обращении парсером к сайту по селектору body — другой вообще не хочет брать пишет вот что:
Подскажите как решить такую проблему: при обращении парсером к сайту по селектору body — другой вообще не хочет брать пишет вот что:
Array
(
[pagetitle] => <h1 class="error">
<span>
<a class="chrome" href="http://www.google.com/chrome" title="Download Chrome"></a>
<a class="firefox" href="http://www.mozilla.com" title="Download Firefox"></a>
<a class="opera" href="http://www.opera.com" title="Download Opera"></a>
<a class="safari" href="http://www.apple.com/safari" title="Download Safari"></a>
<a class="ie" href="http://www.microsoft.com/downloads" title="Download Internet Explorer 9"></a>
</span>
</h1>
<h2 class="title">Обновите браузер</h2>
<p class="message">Просматриваемый вами сайт правильно работает только в современных браузерах. Обновите свой браузер для увелечения безопасности и комфортной работы. Вы можете выбрать один из представленных ниже браузеров. Если все же решите продолжить просмотр, <a href="https://site.ru/?forwardOutdatedBrowser=1">нажмите сюда</a></p>
)
Демон постоянно сыпет ошибками:
pages timeout done
Error: connect ECONNREFUSED 207.241.237.3:443
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1132:16) {
errno: -61,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '207.241.237.3',
port: 443,
config: {
.........
MacBook-Pro:~ alex$ node -v
v16.4.0
В чём может быть дело? уже обновил ноду с 10 до 16 — сильно не помогло. Что я делаю не так?
Не знаю, я на маке не запускал. Возможно в этом дело. На линуксе всё работает, если поднимать по документации.
может тогда docker контэйнер запилить для маководов? провозился наверное целый день — никак не запустил, проще было дождаться php-версии парсера
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.