守护进程意外终止

1 投票
3 回答
1428 浏览
提问于 2025-04-15 15:14

我有一个Python脚本,我用这段代码把它变成后台运行的程序。

        def daemonise():
            from os import fork, setsid, umask, dup2
            from sys import stdin, stdout, stderr

            if fork(): exit(0)
            umask(0) 
            setsid() 
            if fork(): exit(0)

            stdout.flush()
            stderr.flush()
            si = file('/dev/null', 'r')
            so = file('daemon-%s.out'%os.getpid(), 'a+')
            se = file('daemon-%s.err'%os.getpid(), 'a+')
            dup2(si.fileno(), stdin.fileno())
            dup2(so.fileno(), stdout.fileno())
            dup2(se.fileno(), stderr.fileno())
            print 'this file has the output from daemon%s'%os.getpid()
            print >> stderr, 'this file has the errors from daemon%s'%os.getpid()

这个脚本在

while True: try: funny_code(); sleep(10); except:pass;

里循环运行。它能正常运行几个小时,但之后就会意外停止。我要怎么去排查这些后台程序的问题呢?

[编辑]

有没有办法在不启动像monit这样的进程的情况下,用Python写一个监控程序,来监视我的其他后台程序,并在它们停止时重新启动?(谁来监控这个监控程序呢。)

3 个回答

0

我在客户那里用过的一个工具是daemontools。这个工具经过验证,使用起来很可靠,可以让任何程序在后台运行。

你只需要写好你的应用程序,不用考虑后台运行的问题,先让它在前台运行;然后为它创建一个daemontools的服务文件夹,从此以后,它会自动发现并重启你的应用程序,而且每次系统重启时也会自动启动。

这个工具还可以处理日志轮换等事情,省去了很多繁琐的重复工作。

1

你为什么要默默地忽略所有的错误呢?试着看看这些错误是什么:

while True:
    try:
        funny_code()
        sleep(10)
    except BaseException, e:
        print e.__class__, e.message
        pass

可能发生了一些意想不到的事情导致程序出错,但如果你盲目地忽视所有错误,就永远不会知道发生了什么。

我建议你使用supervisord(用Python写的,非常好用)来管理和监控进程。在supervisord下运行,你就不需要使用你的daemonise函数了。

3

你真的应该使用python-daemon这个库,它实现了PEP 3141,这是一个标准的守护进程库。这样可以确保你的应用在任何类型的UNIX系统上都能正常工作。没必要自己重新发明轮子。

撰写回答