【问题标题】:How to wrap python daemon around my code如何在我的代码周围包装 python 守护进程
【发布时间】:2013-06-10 19:22:58
【问题描述】:

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

我想守护它。我一直在反复阅读这个守护进程类示例here,但我不知道它是如何围绕我的服务器代码进行的。我是否只是将 __main__ 中的所有代码放在我覆盖的 run() 中?

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

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

【问题讨论】:

    标签: python daemon tornado


    【解决方案1】:

    尝试在 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/ 目录。

    【讨论】:

    • 我的 python 代码是否必须包含任何分叉代码等才能正常工作,还是可以是一个简单的 python 脚本?
    • 另外,我更喜欢可移植的东西,这样我就可以在没有像这样的主要依赖项的情况下在任何地方运行脚本。
    • 我必须为这个选项投票。 Supervisor 还添加了 CTL 和 Web 界面,您可以使用它们启动/停止服务、查看日志文件等。
    【解决方案2】:

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

    $ 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(): 并从 Daemon 子类的 run() 方法调用它。

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      相关资源
      最近更新 更多