У меня есть карта. На этой карте я хочу показать живые данные, собранные из нескольких таблиц, некоторые из которых имеют поразительное количество строк. Излишне говорить, что получение этой информации занимает много времени. Кроме того, используется pinging. В зависимости от того, какие серверы находятся в автономном режиме или далеко, сбор этих данных может варьироваться от 1 до 10 минут.
Я хочу, чтобы карта была быстрой и отзывчивой, поэтому я решил добавить новую таблицу в свою базу данных, содержащую только данные, необходимые карте. Это означает, что мне нужен фоновый процесс, чтобы постоянно обновлять информацию в моей новой таблице. Конечно, возможности Cron – это возможность, но я хочу, чтобы обновление данных происходило, как только завершился предыдущий интервал. И что, если количество автономных IP-адресов внезапно всплескается, и цикл занимает больше времени, чем интервал задания Cron?
Мое собственное решение – создать бесконечный цикл в PHP, который выполняется по командной строке. Этот цикл будет обновлять данные для карты в MySQL, а также записывать другие полезные данные, такие как время цикла и неудачные попытки на пингах и т. Д., А затем перезапускать после короткой паузы (несколько секунд).
Тем не менее – мне неоднократно говорят люди, что PHP-скрипт работает навсегда BAD. Через некоторое время он будет выкапывать гигабайты ОЗУ (и другие ужасные вещи)
Частично я пишу этот вопрос, чтобы подтвердить, действительно ли это так, но некоторые советы и трюки о том, как я буду писать чистый цикл, который не просачивает память (если это возможно) не пойдет не так. Также будут оценены мнения по этому вопросу.
Ответ, который я чувствую, проливает свет на вопрос, который я укажу как правильный.
Цикл должен быть в одном скрипте, который активирует / вызывает фактический скрипт как другой процесс … как и cron.
Таким образом, даже если утечка памяти и накопленная память накапливаются, она будет / должна быть бесплатной после каждого цикла.
Тем не менее – мне неоднократно говорят люди, что PHP-скрипт работает навсегда BAD. Через некоторое время он будет выкапывать гигабайты ОЗУ (и другие ужасные вещи)
Это было очень верно. Предыдущие версии PHP имели ужасную сборку мусора , поэтому длительные скрипты могли легко случайно потреблять гораздо больше памяти, чем они на самом деле использовали. В PHP 5.3 был введен новый сборщик мусора, который может понимать и очищать циклические ссылки, что является причиной «утечек памяти». Он включен по умолчанию. Проверьте эту ссылку для получения дополнительной информации и хороших графиков.
Пока ваш код принимает меры, позволяющие переменным выходить из области действия в надлежащее время и в противном случае отменять переменные, которые больше не будут использоваться, ваш скрипт не должен потреблять ненужные объемы памяти только потому, что это PHP.
Я не думаю, что это плохо, как и все, что вы хотите работать постоянно, вы должны быть более осторожными.
Есть библиотеки, которые помогут вам в решении этой задачи. Взгляните на System_Daemon , который выпустил RC 1 чуть более месяца назад, что позволяет вам «задавать такие параметры, как максимальное использование RAM».
Вместо того, чтобы запускать бесконечный цикл, у меня возникнет соблазн пойти с параметром cron, который вы укажете в сочетании со входом в таблицу базы данных или плоским файлом, который вы использовали бы для хранения «текущего активного» бита состояния, чтобы убедиться, t имеют перекрывающиеся процессы, пытающиеся работать в одно и то же время.
Хотя я понимаю, что это будет означать небольшую задержку, прежде чем вы выполните следующую итерацию, это, вероятно, лучшая идея:
Это позволит RDBMS выполнять любые ожидающие обновления с низким приоритетом и т. Д., Которые могут быть приостановлены из-за объема выполняемой вами деятельности.
Даже если вы аккуратно отключили все временные переменные, которые вы использовали, все же возможно, что PHP «утешит» память, хотя недавние улучшения (5.2 представили новую систему управления памятью и сборку мусора в 5.3), мы надеемся , меньше проблемы.
В общем, будет также легче справляться с другими проблемами (если соединение с БД временно отключается из-за изменения конфигурации и перезапуска, например), если вы используете подход cron, хотя в идеальном мире вы будете обслуживать такие все равно в вашем коде. (Тем не менее, в последний раз, когда я проверял, это было далеко от идеального мира.)
Сначала я не вижу, как вам нужен сценарий демона, чтобы обеспечить описанную вами функциональность.
Возможности Cron – это, конечно, возможность, но я хочу, чтобы обновление данных произошло, как только предыдущий интервал завершился
Ни задача cron, ни демон – это способ решить проблему (если только демон не станет потоком данных для скриптов). Я создавал бы диссоциированный процесс, когда данные доступны с использованием стратегии блокировки для предотвращения параллелизма.
Длинные сценарии PHP не являются внутренне плохими, но ссылка на подсчет сборщика мусора не имеет отношения ко всем возможным сценариям для очистки памяти, но в более поздних реализациях есть более продвинутый сборщик, который должен очищать намного больше (круговой эталонный контроль).