几个建议:
1、你那个服务进程应该自己daemonize;
2、服务进程应该保存pid到文件;
3、watchdog根据pid文件中的pid检查服务进程是否还在运行中;(运行状态是否正常可以还是用你说的时间比对);
4、一般来说,杀不死那个服务进程是权限问题,所以,可以考虑直接由watchdog作为自己的子进程来启动服务进程。
DIrk
做了一个爬虫程序, 不过运行一段时间后, 总是莫名奇妙的就不工作了, 所以,我需要另外一个监控程序,定时看看爬虫程序工作是否正常,不正常就kill
掉进程,然后重启一个进程。
我是在linux 下面运行程序的。
想法其实特别简单, 别人在网上也提出过这个想法的,就是监控日志文件, 让爬虫程序定时写日志文件(写当前时间), 然后监控程序定时读取监控文件最后一行,
然后和当前时间比较, 如果时间差异在允许范围内,算爬虫工作正常, 否则,就要杀掉爬虫进程,然后重启爬虫。 想法是如此简单,
应该也是有效的,但是运行过程中,发现监控程序无法杀死爬虫进程, 导致系统中运行了一段时间后,有大量的爬虫程序, 要多少有多少。 附代码如下, 望高手,
或者有这方面经验的高手指点一二, 不胜感激。 主要就是我杀掉进程用的是
1, 找爬虫进程ID:
ps_str = 'ps aux |grep %s | grep -v grep' %proc_name
#ps_str = 'ps |grep testlong.py | grep -v grep'
x= os.popen(ps_str).read()
2, 杀进程
os.system('kill %s' %proc_id)
3, 新建一个进程
os.system('./%s &' %proc_name)
是因为那个 & 符号把进程防后台运行了吗, 去掉那个 &符号也不行。 奇怪。
创建进程肯定没问题,可以创建很多个。可是我目前只要有一个进程能好好工作就行,所以我需要在发现进程不工作的时候去杀掉,但是却没办法作到。
下面是一个模拟需要长时间持续运行的一个任务, 比如一个爬虫程序。
#!/usr/bin/env python
#coding=utf-8
'''
$Id$
Filename "longtest.py"
模拟一个需要持久工作的任务
每隔一定时间写日志, 另外一个监控程序定时检查日志,
如果日志最后时间和当前时间差距超过一定值,就杀掉
本程序,然后重新打开这个程序。
'''
import time
import datetime
def main():
print 'now begin at ',datetime.datetime.now()
count = 1
while 1:
count += 1
time.sleep(5)
if count < 10:
str_time = datetime.datetime.strftime(
datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
fp = open('runlog.log','aw')
fp.write('%s\n' %str_time)
fp.close()
print 'still work... %s' %count
# 就是说执行10次之后,模拟本程序死掉了,不写日志了
else:
print 'dont work... %s' %count
print 'done', datetime.datetime.now()
if __name__ == '__main__':
main()
============ 监控程序如下 =============
#!/usr/bin/env python
#coding=utf-8
import os
import datetime
import time
# 要kill掉的进程的名字描述字符串.
proc_name = 'testlong.py'
monit_log = 'runlog.log'
time_allow = 60 # 允许60秒的空闲,超过这个值watchdog 返回0
def log(str):
p = open('proc.log','aw')
p.write('%s %s \n' %(str, datetime.datetime.now()))
p.close()
def watchdog():
'''检查一个日志文件,取出最后一条记录,
取出时间,和当前时间比较,看看是否超时。
超时是time_allow
超时返回 1, 不超时返回 0
'''
fp = open(monit_log,'r')
lastline = fp.readlines()[-1].replace('\n','')
fp.close()
print lastline
t1 = datetime.datetime.strptime(lastline, '%Y-%m-%d %H:%M:%S')
timediff = (datetime.datetime.now() - t1).seconds
print u'上次运行距今 %s 秒' % timediff
#时间比较
if timediff > time_allow:
return 1
else:
return 0
def restart_proc(proc_name):
'''重启指定的进程'''
ps_str = 'ps aux |grep %s | grep -v grep' %proc_name
#ps_str = 'ps |grep testlong.py | grep -v grep'
x= os.popen(ps_str).read()
#log x
if x:
proc = x.split('\n')
for line in proc:
print line
try:
proc_id = line.split()[0]
#log ('got pid: %s and kill it ' %proc_id )
os.system('kill %s' %proc_id)
log ('kill pid %s ok, starting new' %proc_id)
except:
pass
else:
# 没有找到要结束的进程,直接启动该进程
log ('not find proc, start it ')
os.system('./%s &' %proc_name)
def main():
while 1:
if watchdog():
restart_proc(proc_name)
else:
print 'ok, program well'
time.sleep(20)
if __name__=='__main__':
main()
Yours Li Dong