现在假设一个脚本是,hello.py,内容是
fo = open(‘xx.txt‘,‘w‘)
while 1:
fo.write(‘hello world‘)
print(‘hi‘)
time.sleep(1)
如果使用python hello.py那么控制台一直print hi,会干不了其它活,必须再xshell开个窗口。如果 ctrl +c ,那程序直接结束了。
使它在后台工作可以结尾加个 &,但这样把xshell窗口关了,就结束了,可以看看记事本有没有新增就证明这个了。这时候还会在前面加个nohup,所以全部命令是 nohup python hello.py &,这样才行。
nohup会记录程序的log日志,普通的print不会去记录,如果不重定向日志输出,默认是当前文件夹下面生成了一个nohup.out,这个随时间越来越大,往一个大文件里面读写东西势必会慢,而且可能搞满磁盘,查了下需要一段shell脚本来搞这个,很麻烦。
还有我要结束这个hello.py怎么办,要去 ps -ef |grep 。。。。,然后kill,要再重启则需要再一次输入nohup python hello.py &,命令越长越麻烦,当然也可以把命令写到shell脚本来减少输入,但管理起进程来还是麻烦了点。
supervisor正好用到,
supervisord -c xxx.conf启动,如果单独的supervisor那就是默认使用etc/supervisor.conf这个配置了
在etc/supervisor.conf添加程序配置,但是这样十分不太好,配置文件会变得越来越长,
把最下面的include注释取消掉,每个项目使用单独的配置文件,supervisorconfig文件夹下面有两个项目配置文件,*.ini可以包含这两个。
[program:automobile]
command=/root/miniconda3/bin/uwsgi --ini uwsgib.ini ; 程序启动命令
directory=/root/xxxx/automobile
autostart=True ; 在supervisord启动的时候也自动启动
startsecs=10 ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3 ; 启动失败自动重试次数,默认是3
user=root ; 用哪个用户启动进程,默认是root
priority=999 ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数,默认是10
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/root/yangdefeng/touna/automobile/logs/automobile.out
loglevel=debug ;loglevel 指定了日志的级别,用 Python 的 print 语句输出的日志是不会被记录到日志文件中的,需要搭配 Python 的 logging 模块来输出有指定级别的日志。
stopasgroup=true ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=true ;默认为false,向进程组发送kill信号,包括子进程
另一个文件,这次开两个一模一样的进程。
[program:daili]
command=/root/miniconda3/envs/py27/bin/python dailiip.py ; 程序启动命令
directory=/root/xxx/代理ip获取
numprocs=2 ;默认为1,; 若 numprocs 不为1,process_name 的表达式中一定要包含 process_num 来区分不同的进程
process_name=%(program_name)s_%(process_num)02d
autostart=false ; 在supervisord启动的时候也自动启动
startsecs=10 ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3 ; 启动失败自动重试次数,默认是3
user=root ; 用哪个用户启动进程,默认是root
priority=999 ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数,默认是10
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/root/yangdefeng/touna/代理ip获取/logs/daili.out
loglevel=debug ;loglevel 指定了日志的级别,用 Python 的 print 语句输出的日志是不会被记录到日志文件中的,需要搭配 Python 的 logging 模块来输出有指定级别的日志。
stopasgroup=false ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false ;默认为false,向进程组发送kill信号,包括子进程
比如我分布式爬虫,先开两个一模一样的进程,当然可以在py中用multiprocessing弄出两个进程来,也可以把脚本运行两次不就是两个进程吗。
那么可以指定numprocs=2,nmprocess大于1的时候,一定要设置process_name=%(program_name)s_%(process_num)02d,后面的格式名字随便,总之要能分辨出来是两个嘛,不然supervisorctl start programe时候怎么知道启动什么进程。如果不设置程序名启动supervisord服务时候会报错的。
使用supervisorctl进入supervisor客户单管理
start xx
stop xx 来启动和停止程序。
reload update在配置修改需要生效时候可以使用。
也可以开启web服务来管理程序,在配置中需要把注释去掉;
输入linux的地址加上9001端口,使用账号和密码登录后就能看到程序状态了。这上面可以控制清楚的知道,启动了那些程序,和控制程序的启动和停止,点击tail -f可以在web中看到程序的日志信息了,不用去xshell中去用tali -f查看了。
很方便的东西,可以用来管理python和非python程序。顺便轻松解决了nohup的日志大小切割问题。
原文:http://www.cnblogs.com/ydf0509/p/7747883.html