Скрипт Python как служба/демон linux


Здравствуй,

Я пытаюсь позволить скрипту python работать как служба (демон) на (ubuntu) linux.

в интернете существует несколько решений, таких как:

http://pypi.python.org/pypi/python-daemon/

хорошо управляемый процесс демона Unix сложно получить правильно, но необходимые шаги во многом одинаковы для каждой программы демона. Экземпляр DaemonContext содержит поведение и настроенную среду процесса для используйте экземпляр в качестве контекстного менеджера для входа в состояние демона.

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

однако, поскольку я хочу интегрировать свой скрипт python специально с ubuntu linux, мое решение представляет собой комбинацию с инициализацией.D скрипт

#!/bin/bash

WORK_DIR="/var/lib/foo"
DAEMON="/usr/bin/python"
ARGS="/opt/foo/linux_service.py"
PIDFILE="/var/run/foo.pid"
USER="foo"

case "" in
  start)
    echo "Starting server"
    mkdir -p "$WORK_DIR"
    /sbin/start-stop-daemon --start --pidfile $PIDFILE 
        --user $USER --group $USER 
        -b --make-pidfile 
        --chuid $USER 
        --exec $DAEMON $ARGS
    ;;
  stop)
    echo "Stopping server"
    /sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose
    ;;
  *)
    echo "Usage: /etc/init.d/$USER {start|stop}"
    exit 1
    ;;
esac

exit 0

и в python:

import signal
import time
import multiprocessing

stop_event = multiprocessing.Event()

def stop(signum, frame):
    stop_event.set()

signal.signal(signal.SIGTERM, stop)

if __name__ == '__main__':
    while not stop_event.is_set():
        time.sleep(3)

мой вопрос сейчас, если этот подход является правильным. Должен ли я обрабатывать какие-либо дополнительные сигналы? Будет ли это"хорошо управляемый процесс демона Unix"?

2 67

2 ответа:

предполагая, что ваш демон имеет какой-то способ непрерывного запуска (какой-то цикл событий, скрученный, что угодно), вы можете попробовать использовать upstart.

вот пример конфигурации выскочки для гипотетической службы Python:

description "My service"
author  "Some Dude <blah@foo.com>"

start on runlevel [234]
stop on runlevel [0156]

chdir /some/dir
exec /some/dir/script.py
respawn

если вы сохраните это как сценарий.conf to /etc/init вы просто делаете один раз

$ sudo initctl reload-configuration
$ sudo start script

вы можете остановить его с stop script. То, что выше выскочка conf говорит, чтобы запустить эту службу при перезагрузке, а также перезапустить его, если он умирает.

как для обработка сигналов - ваш процесс должен естественно реагировать на SIGTERM. По умолчанию это должно быть обработано, если вы специально не установили свой собственный обработчик сигналов.

ответ Rloton хорош. Вот легкая доработка, просто потому, что я потратил кучу времени на отладку. И мне нужно сделать новый ответ, чтобы я мог правильно форматировать.

еще пара пунктов, которые заняли у меня целую вечность, чтобы отладить:

  1. когда это не удается, сначала проверьте /var/log/upstart/.журнал
  2. если ваш скрипт реализует демон с python-daemon, вы не используете строфу 'expect daemon'. Не имея "ожидать" работает. Я не знаю, почему. (Если кто знает, почему - пожалуйста, напишите!)
  3. кроме того, продолжайте проверять "сценарий состояния initctl", чтобы убедиться, что вы (запуск/запуск). (и сделать перезагрузку при обновлении файла conf)

вот мой вариант:

description "My service"
author  "Some Dude <blah@foo.com>"

env PYTHON_HOME=/<pathtovirtualenv>
env PATH=$PYTHON_HOME:$PATH

start on runlevel [2345]
stop on runlevel [016]

chdir <directory>

# NO expect stanza if your script uses python-daemon
exec $PYTHON_HOME/bin/python script.py

# Only turn on respawn after you've debugged getting it to start and stop properly
respawn