LinuxForum.Fans
Тема

Многопоточность и повторяющийся параметр

Автор: valet 27 сообщений 7800 просмотров
#304029
"valet" написал:
постараюсь объяснить на примере одного из моих скриптов. Например я написал простенький web-паук на php, который собирает нужную мне статистику. Его функционал в двух словах примерно такой: взять с sqlite-базы ссылку, загрузить страницу, собрать с нее по нужному критерию исходящие ссылки с нее и положить в ту же sqlite-базу. То есть каждый запуск такого скрипта будет проделывать это постоянно увеличивая базу. Тут по понятным причинам не получится применить организовать какой-то цикл внутри скрипта - да и не надо этого.

Я не вижу тут неразрешимых проблем. Что вас смущает?

"valet" написал:
Ну и еще по поводу цикла внутри скрипта - ну никак даже если бы это было логично - для веб-скриптов существует понятие "время выполнения скрипта", он не может выполнятся вечно или очень долго - его как минимум отклонит вебсервер по таймауту.

Внезапно скрипт можно вызывать из cli с set_time_limit(0). Без ограничений по времени выполнения, wget'а, баша и дерганий веб сервера. И он сможет дергать ссылки ничуть не хуже, чем под управлением веб сервера.

#304032

"-=Serj=-" написал:
Ну, насколько я понимаю, цикл присутствует внутри xargs.
Ну насколько я понимаю, не совсем так. насколько мне видется его работа - xargs принимает параметры и разделяет эти параметры (по описанным в параметрам xargs например n1 - брать и передавать по одному параметру из входного потока) для передачи в скрипт тоже параметрами.
То есть например
text
cat urls | xargs -t -P 3 -n1 wget --quiet -O -

эквивалентно примерно следующем группам команд, выполняющимся пока не кончатся входные параметры для xargs, то есть пока не закончится вывод cat:

text
wget --quiet -O - http://url1_iz_urls & wget --quiet -O - http://url2_iz_urls & wget --quiet -O - http://url3_iz_urls
&&
wget --quiet -O - http://url4_iz_urls & wget --quiet -O - http://url5_iz_urls & wget --quiet -O - http://url6_iz_urls
&&
...
wget --quiet -O - http://urln-2_iz_urls & wget --quiet -O - http://urln-1_iz_urls & wget --quiet -O - http://urln_iz_urls

Ну и на мое удивление все это работает без какой либо нагрузки на процессор - деталей как это все организовано я не знаю, но это факт. Хотя бы потому что десятки таких скриптов запускаются подобным образом и LA при это стремится к нулю.

#304033

"neol" написал:
Внезапно скрипт можно вызывать из cli с set_time_limit(0). Без ограничений по времени выполнения, wget'а, баша и дерганий веб сервера. И он сможет дергать ссылки ничуть не хуже, чем под управлением веб сервера.
Можно, пробовал, мне не нравится. Там какие-то другие проблемы начинаются, сейчас точно не вспомню, но точно помню, что рассматривал это, но что-то меня потом остановило так делать.
Да и зачем это? Что это даст? Архитектура постановки задачи мне кажется тут правильно выполнена, скрипт простейший - взять с базы что-то, обработать, положить...

Да и вообще - сам язык php не рассчитан на это, это язык для веба, в таком случае такого паука уже лучше было бы писать на C или скажем каком-то серверном языке типа Python, но я просто написал на чем смог. Да и вопрос даже не конкретно в этом скрипте, у меня десятки подобных скриптов и все запускаю вот таким вот костылем через cat и xargs, просто считаю как-то тупо создавать файл с 100500 одинаковыми урл-ами.
#304081
"valet" написал:
Можно, пробовал, мне не нравится.
"valet" написал:
Да и вопрос даже не конкретно в этом скрипте, у меня десятки подобных скриптов и все запускаю вот таким вот костылем через cat и xargs, просто считаю как-то тупо создавать файл с 100500 одинаковыми урл-ами.

Ну нравится делать через задницу, так не удивляйтесь, что плохо пахнет.

"valet" написал:
Да и зачем это? Что это даст?

Это выгоднее по ресурсам. И вообще правильнее, чем городить костыли.

"valet" написал:
Да и вообще - сам язык php не рассчитан на это, это язык для веба, в таком случае такого паука уже лучше было бы писать на C или скажем каком-то серверном языке типа Python, но я просто написал на чем смог

18,5 миллионов результатов по запросу "php daemons" как бы намекают, что всем пофиг на что он рассчитан.

#304173

Спасибо всем за участие в теме, расскажу к чему пришел.

Использую этот вариант:

"neol" написал:
for i in {1..100500}; do echo "http://site.ru/script.php"; done | xargs -t -P 10 -n1 wget --quiet -O -

Пришел к выводу, что это лучший выход в данной ситуации. Да, вывод cat с file легче для процессора чем цикл, но ведь тот же файл я таким же циклом и генерю :), записываю в него 100500 одинаковых строк - так что цикл этот, как правильно заметил -=Serj=-, никуда и так не деть :). Вот в моем прежнем варианте кроме плохого стиля, нагрузки на процессор во время цикла еще и в IO вливалось...

"neol" написал:
Ну нравится делать через задницу
через задницу, это использовать php через cli (он для этого мягко говоря не совсем предназначен) и заодно появляется куча подводных камней - грубо говоря чтобы вызывать с консоли
text
php script.php

надо этот самый скрипт чуть менее чем полностью :) переписать, уже не говоря о дополнительных требованиях при использовании php через cli, почитайте с хабра про сабж, если интересно.
Собственно я вот сейчас вспомнил почему я в свое время отказался от такой затеи - грубо говоря полностью рабочий (если вызывать по-человечески - то есть по http-протоколу с задействованием веб-сервера) и оттестированный скрипт отказался правильно работать через cli, выдавая при это кучу ошибок и ворнингов да еще и почему-то намного медленее, если таковых запустить множество...

"neol" написал:
Это выгоднее по ресурсам.
Это очень спорное утверждение. Могу сказать, что накладные ресурсы затрачиваемые вебсервером (я практикую всегда только nginx + php-fpm) ничтожно малы по сравнению с скриптами. Поэтому ничего страшного в вызове php-скриптов привычным методом я не вижу. И вот это уже не знаю почему, выполняются они быстрее чем через cli. Ну в конце-концов это работает и работает быстро - а как говорится, работает - не трогай :)
#304251
"valet" написал:
грубо говоря чтобы вызывать с консоли

php script.php

надо этот самый скрипт чуть менее чем полностью :) переписать, уже не говоря о дополнительных требованиях при использовании php через cli, почитайте с хабра про сабж, если интересно.

Если код написан нормально, то ему пофиг откуда его вызвали. Кроме обработки сигналов и, возможно, аргументов ничего из перечисленного в статье не окажет сильного влияния на содержание скриптов.

"valet" написал:
Собственно я вот сейчас вспомнил почему я в свое время отказался от такой затеи - грубо говоря полностью рабочий (если вызывать по-человечески - то есть по http-протоколу с задействованием веб-сервера) и оттестированный скрипт отказался правильно работать через cli, выдавая при это кучу ошибок и ворнингов да еще и почему-то намного медленее, если таковых запустить множество...

unit тесты для него вы точно не писали (:

"valet" написал:
Это очень спорное утверждение. Могу сказать, что накладные ресурсы затрачиваемые вебсервером (я практикую всегда только nginx + php-fpm) ничтожно малы по сравнению с скриптами. Поэтому ничего страшного в вызове php-скриптов привычным методом я не вижу. И вот это уже не знаю почему, выполняются они быстрее чем через cli.

"Выгоднее по ресурсам" и "потребляет меньше памяти/процессора/iops/дискового пространства" - это не синонимы. Процесс, запущенный с низким приоритетом, не будет мешать обрабатывать запросы в моменты пиковой нагрузки даже если он требует больше ресурсов.

Сокеты веб сервера (или php-fpm) - это тоже ресурс, причем достаточно ценный. Конечно если ваш сервер обслуживает клиентов, а не предназначен только для внутренних целей. На более-менее нагруженных проектах занимать сокет на длительное время ради какого-нибудь парсера вообще безумно расточительно.

Скрипты из cli выполняются медленнее например из-за apc/eaccelerator/xcache/zend optimizer (нужное подчеркнуть).
В статье по вашей ссылке это написано, кстати говоря.

#304264
"neol" написал:
Если код написан нормально, то ему пофиг откуда его вызвали.
после чего сразу же противоречите себе же :)
"neol" написал:
Кроме обработки сигналов и, возможно, аргументов ничего из перечисленного в статье не окажет сильного влияния на содержание скриптов.

"neol" написал:
unit тесты для него вы точно не писали (:
конечно нет, какие тесты, если я написал скрипт (ну да, как умею), протестил его, убедился в правильности, тут возникла идея запустить проямо из командной строки - запустил, вообще не заработало, пошел редактировать, поменял метод приема параметров и т.д. и т.п., заработало, но засыпало ворнингами, попробовал многопоточно - намного медленнее все это...

"neol" написал:
Процесс, запущенный с низким приоритетом, не будет мешать обрабатывать запросы в моменты пиковой нагрузки даже если он требует больше ресурсов.
мне как раз и не надо уменьшать приоритет - скрипты на рассматриваемом сервере - это основная его работа.

"neol" написал:
Сокеты веб сервера (или php-fpm) - это тоже ресурс, причем достаточно ценный. Конечно если ваш сервер обслуживает клиентов, а не предназначен только для внутренних целей. На более-менее нагруженных проектах занимать сокет на длительное время ради какого-нибудь парсера вообще безумно расточительно.
возможно вы не знаете, для этого существует механизм пулов, которые в находятся в /etc/php5/fpm/pool.d/. Настраиваем пул forscripts.conf с нужными параметрами - с большим количество чилдренов и запросов на чилдрен и т.д. под скрипты и другой пул forsites.conf - под сайты, там уже чилдренов пару штук хватит. Пулы никак друг на друга не влияют, абсолютно независимы и даже если скриптовый пул перегружен или даже перестанет отвечать от нагрузки и скрипты перестанут обрабатываться, то пул для сайтов при этом продолжит работать. На одном из серверов у меня так и организовано - полет нормальный.
Но повторюсь, рассматриваемый сервер исключительно для работы и тестирования скриптов. Собственно я и хочу использовать все его ресурсы именно для этого.

"neol" написал:
Скрипты из cli выполняются медленнее например из-за apc/eaccelerator/xcache/zend optimizer (нужное подчеркнуть).
В том числе, да, у меня для кеширования байт-кода стоит акселератор php-apc, в случае с cli как я понял он тупо не задействуется - это тоже проигрыш и при значительной многопоточности очень ощутимый, так как приходится заново компилировать сотни скриптов.
Войдите или зарегистрируйтесь, чтобы ответить.