守护进程意外终止
我有一个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系统上都能正常工作。没必要自己重新发明轮子。