Запустите скрипт Python с супервизором
Я скопировал отсюда, чтобы запустить мой код Python как демон. Для дополнительного времени работы. Я подумал, что было бы лучше использовать Supervisor, чтобы этот демон работал.
Я сделал это.python_deamon.conf
[program:python_deamon]
directory=/usr/local/python_deamon/
command=/usr/local/python_venv/bin/python daemon_runnner.py start
stderr_logfile=/var/log/gunicorn.log
stdout_logfile=/var/log/gunicorn.log
autostart=true
autorestart=true
Проблема в том, что хотя supervisor успешно запускает python_daemon, он продолжает повторять попытки.
2015-09-23 16:10:45,592 CRIT Supervisor running as root (no user in config file)
2015-09-23 16:10:45,592 WARN Included extra file "/etc/supervisor/conf.d/python_daemon.conf" during parsing
2015-09-23 16:10:45,592 INFO RPC interface 'supervisor' initialized
2015-09-23 16:10:45,592 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2015-09-23 16:10:45,592 INFO supervisord started with pid 13880
2015-09-23 16:10:46,595 INFO spawned: 'python_deamon' with pid 17884
2015-09-23 16:10:46,611 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:47,614 INFO spawned: 'python_deamon' with pid 17885
2015-09-23 16:10:47,630 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:49,635 INFO spawned: 'python_deamon' with pid 17888
2015-09-23 16:10:49,656 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:52,662 INFO spawned: 'python_deamon' with pid 17891
2015-09-23 16:10:52,680 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:53,681 INFO gave up: python_deamon entered FATAL state, too many start retries too quickly
Просто для записи после переопределения run()
метод я никогда ничего не возвращаю.
Можно ли делать то, что я пытаюсь сделать, или я тупой?
PS: я знаю, что основная причина всей проблемы заключается в том, что так как run() никогда не возвращает ничего, супервизор продолжает пытаться запустить его и, следовательно, считает, что процесс завершился неудачно, и дает статус FATAL Exited too quickly (process log may have details)
,
Мой актуальный вопрос: правильно ли я делаю? или это можно сделать так?
PPS: автономно (без руководителя) daemon_runnner.py
работает нормально с разрешениями sudo и без них.
5 ответов
Попробуйте установить startsecs = 0:
[program:foo]
command = ls
startsecs = 0
autorestart = false
http://supervisord.org/configuration.html
startsecs
Общее количество секунд, которое необходимо программе для запуска после запуска, чтобы считать запуск успешным. Если программа не будет работать в течение многих секунд после запуска, даже если она завершается с "ожидаемым" кодом выхода (см. Коды выхода), запуск будет считаться неудачным. Установите 0, чтобы указать, что программе не нужно работать в течение определенного периода времени.
Это то, что я обычно делаю:
- Создать
service.conf
файл, который описывает новый скрипт Python. Этот скрипт ссылается на скрипт оболочки, который в действительности запускает скрипт Python. это.conf
файл живет в/etc/supervisor/conf.d
- Создайте скрипт оболочки, который запускает скрипт Python. Измените права на исполняемый файл.
chmod 755 service.sh
, В этом скрипте мы фактически запускаем скрипт Python. - Сконфигурируйте log_stderr и stderr_logfile для проверки проблемы.
- Обновите супервизор с помощью перезагрузки, а затем проверьте статус:
руководитель> статус
alexad RUNNING pid 32657, время безотказной работы 0:21:05
service.conf
[program:alexad]
; Set full path to celery program if using virtualenv
command=sh /usr/local/src/gonzo/supervisorctl/alexad.sh
directory=/usr/local/src/gonzo/services/alexa
log_stdout=true ; if true, log program stdout (default true)
log_stderr=true ; if true, log program stderr (default false)
stderr_logfile=/usr/local/src/gonzo/log/alexad.err
logfile=/usr/local/src/gonzo/log/alexad.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
; Set Celery priority higher than default (999)
priority=500
service.sh
#!/bin/bash
cd /usr/local/src/gonzo/services/alexa
exec python reader.py
Вы должны проверить журналы программы супервизора, которые обычно находятся здесь./var/log/supervisor/
В моем случае у меня был
Я обнаружил эту странную причину, когда запускал скрипт напрямую, он работал нормально.
После попытки запустить скрипт сsudo
Я понял, что происходит.
Импорт Python относится к пользователю, а не к папке. Поэтому, если вы устанавливаете python или pip с вашим текущим зарегистрированным пользователем и пытаетесь запустить тот же скрипт, что и sudo или какой-либо другой пользователь, он, вероятно, вернетсяModuleNotFoundError: No module named 'somemodule'
Supervisor по умолчанию запускается как root
Я решил это, установивuser
в файле конфигурации супервизора для текущего пользователя, который в моем случае ubuntu:
[program:some_program]
directory=/home/ubuntu/scripts/
command=/usr/bin/python3 myscript.py
autostart=true
autorestart=true
user=ubuntu
stderr_logfile=/var/log/supervisor/myscriptlogs.err.log
stdout_logfile=/var/log/supervisor/myscriptlogs.out.log
В качестве примечания: также важно убедиться, что ваш Supervisorcommand= вызывает скрипт из предполагаемой версии Python.
cd
в папку, где живет ваш скрипт, и запуститеwhich python
и использовать это
Ваш скрипт не работает со статусом выхода. Supervisor просто пытается перезапустить скрипт.
Supervisor запускается с правами root, возможно, он дает эти разрешения вашему сценарию, и это приводит к его сбою (изменение в исходном каталоге или что-то в этом роде). Проверьте, что происходит, когда вы запускаете своего демона как root без Supervisor.
Нам действительно нужно больше информации, чтобы понять, почему это не помогает.
Не уверен, что проблема аналогична работе с демоном, но если вы используете контекст демона напрямую и используете supervisord, вам нужно установить context.detach_process в False