Реклама: виды гвоздик, платья Allure Diagonal, способы похудеть
Возможно, Вам приходилось когда-то писать скрипты, где совершалось какое-то долгое и нудное действие. Ну например – грабился сайт или создавалось 10000 картинок с вотермарками. И вот ведь какое дело – совершенно непонятно, там вообще что-нибудь работает или все повисло? Особенно это тяжело, когда скрипт находится на стадии тестирования. Может быть он пошел по замкнутому кругу (ну скажем начал обрабатывать фотографии заново), а мы не в курсе?
Я сейчас дописывал паука, который просто ползает по одному и тому же сайту (наподобие того, который у гугла или яндекса, только гораздо скормнее). Понятно, мне тестировать его тяжело – а вдруг он по одним и тем же ссылкам полез? А я не знаю? Или еще что-нибудь этакое, залез, например, на внешний сайт по ошибке и по нему пошел? И я придумал два способа для управления и слежения за подобного рода скриптами.
Итак, мониторинг. У меня там все просто – паук знает ссылки, которые еще не обошел и количество страниц, которое уже обошел, две переменные.
Создаем функцию а-ля
function logit($msg){
$file = @fopen («log.txt», «w»);
@fwrite ($file, $msg);
@fclose ($file);
}
И в нашем «мега-цикле» вызываем logit ($var1.$var2); – все. Обе переменные записались в файл. А это значит, что я могу открыть его через браузер и лицезреть в реальном времени прогресс обхода (переменные var1 и var2 изменяются и записываются в файл). Жми F5, да радуйся.
Например, мой паучОк обошел мой же блог за 2 минуты и нашел 450 страниц (в Яше 400, в гугле 240) и я лицезрел меняющиеся цифры в такой вот строчке: «done: 450, fifo: 0, time: 130.87 sec» (это для примера, я не о пауках конкретно)
Дальше, управление.
Немного продолжаю свою мысль. Понятно, что когда скрипт «ушел» в работу, то мы уже можем не дергаться – никакие кнопки и прочие шаманства в браузере работать не будут (даже аякс, скрипт-то в «бесконечном» цикле).
А что, если использовать другой файл как шлюз для общения со скриптом? Ну например, скрипт во время выполнения записывает прогресс в вышеприведенный файл, а из другого периодически читает – что ему нужно делать. Если файл пустой, то скрипт спокойно выполняется. А если в файле появилась запись stop, например, то скрипт аварийно завершается (выход из цикла или вообще exit). Плюс к этому можно создать другой скрипт, скрипт-повелитель :), при запуске которого основной скрипт (у меня – паук) будет останавливаться.
Я имею ввиду, вот запустил я crawler.php. Он там чего-то делает, я не знаю что. Я могу даже браузер закрыть, т.к. от этого процесс не завершится, а я уже останусь вообще без контроля. Но есть чудо скрипт stop.php, я запускаю его, он пишет в какой-то файл типа gate.txt слово «stop», а crawler.php этот файл периодически проверяет и если находит такое слово – прекращает работать.
Кстати, я раньше думал, что если нажать «стоп» в браузере – скрипт тоже остановится. Хрен, как бы не так. Он будет работать, пока не сделает все, что надо. А если он войдет в бесконечный цикл, то он не остановится. Так что достаточно запустить 50 таких скриптов и можно перезагружаться смело.
Такие вот идеи в 4.35 утра.
Оставьте свой комментарий
|
11.03.2009 в 11:57 дп
Да, скрипты работают до упора. Иногда проще перезагрузить сервер…
11.03.2009 в 12:42 пп
Проще мониторить наличие файла(ов) – stop_crawler.flag и т.п.
Ещё хорошобы разграничить доступ, чтобы к одному файлу на запись несколько потоков разом не обратились.
я вот так блокировал, когда на php писал :
$fp=fopen($desc_conf_file,"a+");
$result=lockfile($fp,$desc_lock_file);
if ($result==TRUE) {
# успешная блокировка
} else {
# неуспешная блокировка
echo "$task незаблокированно";
}
fclose($fp);
только было неудобно, когда скрипт до разблокировки падал и приходилось руками файл-флаг удалять.
11.03.2009 в 3:57 пп
profiter, файл-флаг по-моему не очень удобно тем, что, собственно, файл постоянно создается. Значит нужен каталог на запись. Да и вообще… В моем случае можно записывать в файл не только «stop», но и другие команды.
У меня предполагается, что только 1 такой процесс работает одновременно, поэтому он перед собственным запуском очищает файл команд, чтобы сразу же не остановиться :) Осталось только сделать так, чтобы действительно только 1 процесс можно было запустить. Честно говоря, пока не знаю как это на PHP реализовать, да и можно ли это сделать в принципе, когда PHP работает через Apache – с процессами работал только на C++.
11.03.2009 в 4:30 пп
Насколько я знаю каких-то опций на запуск определённого php только одним потоком в апаче нет. Но блокировкой это решается без проблем.
Чтобы не зависала при ошибочном вылете скрипта, когда блокировка не снимается, можно сделать пинг времени изменения файла-флага. Если изменялся 15 мин. назад ( допустим ), то можно смело удалять файл-флаг и запускаться как основной поток. Во время работы скрипта соответственно надо постоянно менять время изменения файла-флага на текущее.
Если придумаешь более грамотно, то пиши в блоге.
12.03.2009 в 12:19 дп
memcached вам в помощь, господа! протестировано на десяти потоках в стиле: прочел – переписал :) :cool:
15.03.2009 в 9:29 дп
Ну насколько я знаю, в PHP с процессами работать нельзя
17.03.2009 в 1:21 пп
Пасибо, интересно!
Мне эта статья пригодится…
А то скоко можно сервак перезагружать))