Python脚本作为linux服务/守护进程

你好,

我试图让一个Python脚本作为服务(守护进程)在(Ubuntu的)Linux上运行。

在networking上有几个解决scheme,如:

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

一个行为良好的Unix守护进程是很难得到的,但是对于每个守护进程来说,所需的步骤都是相同的。 DaemonContext实例保存程序的行为和configuration的进程环境; 使用该实例作为上下文pipe理器来进入守护进程状态。

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

但是,因为我想要集成我的python脚本专门与Ubuntu的Linux我的解决scheme是一个init.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 "$1" 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守护进程”?

假设你的守护进程有一些连续运行的方式(一些事件循环,扭曲,不pipe),你可以尝试使用upstart

以下是一个假设的Python服务的示例upstartconfiguration:

 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 

如果将此脚本另存为/etc/init ,则只需执行一次即可

 $ sudo initctl reload-configuration $ sudo start script 

你可以stop script来停止它。 上面这个暴发户说的是在重新启动的时候启动这个服务,如果死了,也要重新启动。

至于信号处理 – 你的过程自然会对SIGTERM做出反应。 默认情况下这应该被处理,除非你已经专门安装了你自己的信号处理器。

Rloton的答案很好。 这仅仅是因为我花费了大量的时间进行debugging,所以这是一个轻微的改进。 我需要做一个新的答案,所以我可以正确格式。

其他几点让我永远debugging:

  1. 失败时,首先检查/var/log/upstart/.log
  2. 如果你的脚本使用python-daemon来实现一个守护进程 ,那么你不要使用'expect守护进程'节。 没有“期望”的作品。 我不知道为什么。 (如果有人知道为什么 – 请发布!)
  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