Я планирую создать скрипт на Python, который отслеживает некоторые внешние параметры и действует на основе полученных данных. Проверка в основном заключается в выполнении http-вызова на сервере в сети, и если ответ не соответствует ожиданиям, выполните еще один http-вызов на другом сервере в сети.
Скрипт будет иметь 60-секундный интервал проверки и, надеюсь, будет продолжать проверку бесконечно.
Вот урезанная версия того, что у меня сейчас есть
import time
if __name__ == '__main__':
while True:
runCheckfunction()
time.sleep(60)
Это очень просто, что заставляет меня сомневаться, не может быть все так просто, верно?
Обеспокоенность:
Во время сна я беспокоюсь, что этот сценарий может использовать чрезмерные ресурсы ЦП, что может вызывать беспокойство, поскольку он будет запускаться на встроенной машине.
Утечка памяти. Хотя это очень маловероятно, и если это произойдет, то это не будет в части бесконечного цикла, а будет в runCheckFunction() из-за моего плохого программирования. После выхода из функции можно ли предположить, что она освобождает всю использованную память? У меня нет глобальных переменных, и все находится внутри этой функции?
Есть ли для этого лучшие методы? вроде стандартного модуля, о котором я не знаю, который предназначен именно для этой цели?
@Barmar, так это действительно лучший способ бесконечно зацикливаться?
Альтернативы практически нет.
Помимо того, что сказал Бармар, используйте инструмент контроля процессов, чтобы перезапустить службу в случае сбоя (в современных дистрибутивах в основном это systemd, но в некоторых встроенных системах используется альтернативный). Вы также можете настроить его для работы в ограниченном пространстве имен, чтобы он завершал работу и перезапускался при достижении верхней отметки, значительно ниже того, что может повлиять на другие службы на том же устройстве.
Все локальные переменные функции исчезают после ее возврата. Поэтому, если он не добавляет что-то к глобальной переменной, утечки памяти не будет.
Я бы сказал, что задание cron (или системный таймер) — гораздо лучший вариант.
Тем не менее, мой бывший руководитель был параноиком в отношении программ с бесконечными циклами. Он заставлял их выходить после N итераций, а супервайзер перезапускал процесс.
@mx0, зависит от того, насколько ограничена среда процессором; запуск новых процессов не является бесплатным. Использование сторожевого таймера и ограничений ресурсов позволяет оплачивать затраты на перезапуск только тогда, когда это необходимо, а не иначе.
Это совершенно прекрасная реализация. Единственный недостаток, который я вижу, это то, что в нем жестко запрограммировано 60 секунд. Cronjob или внешний планировщик могут быть одним из способов извлечь это. Если вас беспокоит зависание задания или утечка памяти, то внешний планировщик также поможет в этом, но я бы предпочел какое-то время понаблюдать за этим и посмотреть, есть ли у него какие-либо проблемы, на которые стоит потратить время.
О, я полагаю, есть еще одно соображение для цикла while True
, хотя и незначительное. Возможно, вы захотите поймать KeyboardInterrupt
, чтобы выйти более изящно. Это не особо вредно, просто немного спам.
Согласен с Кодзиро; Оставьте аспект синхронизации в сценарии Python и позвольте планировщику ОС обрабатывать его запуск.
Если вас беспокоят утечки памяти, вы можете использовать, например. Параметры Systemd RuntimeMaxSec
и Restart
, позволяющие время от времени перезапускать ваш скрипт.
@CharlesDuffy, это верная точка зрения. Но если этот сценарий нетривиален, со временем он может (будет) тормозить. Вы можете попытаться перехватить все возможные исключения и каким-то образом восстановить их или позволить им умереть и перезапустить их. Без задания cron вам понадобится сценарий мониторинга для вашего сценария мониторинга.
Понятно, похоже, что скрипт Python настолько хорош, насколько это возможно. Что касается решения, выходящего за рамки сценария, кажется единодушным, что лучшим подходом является настройка задания cron.
@ mx0, да, и я уже довольно давно выступаю за надзор за процессом в этой теме.
Похоже, это сценарий без сохранения состояния, который вы хотите периодически запускать.
Вместо того, чтобы использовать Python для периодического запуска, почему бы не использовать задание cron, которое вызывает ваш скрипт с вашим интервалом.
преимущества:
установить:
crontab -e
* * * * * /usr/bin/python3 /path/to/your/script/test.py
аналогичный вариант, служба systemd. Создайте служебный файл /etc/systemd/system/test_script.service
:
[Unit]
Description=Run Python script every 60 seconds
[Service]
ExecStart=/usr/bin/python3 /path/to/your/script/test.py
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
Альтернативные варианты: signal
библиотека
Если вы хотите использовать systemd с регулярными перезапусками, правильный способ сделать это — использовать модуль .timer
и Type=oneshot
на соответствующем модуле .service
, а не использовать Restart=always
.
сон практически не использует ресурсы. Операционная система блокирует процесс до истечения таймера.