如何围绕我的代码包装python守护进程

时间:2013-06-10 19:22:59

标签: python daemon tornado

我现在有一个使用Tornado的工作服务器,根据答案:Python BaseHTTPServer and Tornado

我想要守护它。我一直在阅读这个守护进程类示例here,但我无法弄清楚它是如何包裹我的服务器代码的。我是否只将__main__中的所有代码放入我覆盖的run()中?

如果它在另一个文件中,我如何将它子类化?确保它在同一目录中并使用不带.py扩展名的文件名导入?

我只是在寻找运行我的python Web服务器脚本的最简单方法,只需要一个简单的调用,例如./startserver.sh(例如,如果我要使用bash脚本)并让它运行在后台没有nohup.out文件,所有stdout和stderr都重定向到日志文件。

2 个答案:

答案 0 :(得分:4)

尝试在Linux上使用supervisor守护程序包。它可以让你轻松地守护它。

对于Ubuntu:sudo apt-get install supervisor

创建conf.d文件:

cd /etc/supervisor/conf.d/ vim pyhttpd.conf

pyhttpd.conf内:

[program:pyhttpd]
directory=/path/to/project
environment=ENV_VAR=ENV_VAL,ENV_VAR2=ETC
command=startserver.sh
autostart=true
autorestart=true

最后,使用新配置更新supervisor

supervisorctl update

它应该为您启动,现在无论何时启动都会运行。


这些命令也可用:

supervisorctl stop pyhttpd

supervisorctl start pyhttpd

supervisorctl restart pyhttpd


stdoutstderr已记录到/var/log/supervisor/目录。

答案 1 :(得分:0)

让我们保持简单。项目树:

$ tree
.
├── daemon.py
├── main.py
├── server.py
└──  __init__.py

daemon.py是来自http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/的守护程序类,server.py是来自Python BaseHTTPServer and Tornado的线程版代码,__init__.py是一个允许我们导入的空文件来自目录中其他文件的代码。 main.py是:

#!/usr/bin/env python

import sys, time, threading
from daemon import Daemon
from server import run_tornado, run_base_http_server

class ServerDaemon(Daemon):
    def run(self):
        threads = [
            threading.Thread(target=run_tornado),
            threading.Thread(target=run_base_http_server)
        ]

        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()

if __name__ == "__main__":
    daemon = ServerDaemon('/tmp/server-daemon.pid')

    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()          
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

使用以下命令运行:

$ python main.py start

对于从Python BaseHTTPServer and Tornado更改 if __name__ == '__main__':def myfun():的第一个版本,并从run()子类的Daemon方法调用它。