简介
推荐一个好用的进程管理程序,再也不用坑爹的screen
跑程序了。
先放官方介绍:supervisor介绍(英)
总结一下:
- Supervisor是用
Python
开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon
,并监控进程状态,异常退出时能自动重启。 - 它是通过
fork/exec
的方式把这些被管理的进程当作supervisor
的子进程来启动,这样只要在Supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。
声明
本文根据以下博客部分观点加上作者自己的一点看法汇聚而成,感谢这些作者。
环境
系统:
ubuntu 14.04
supervisor:3.0b2
时间:2018-8
安装
配置
子进程配置
一般情况下,
supervisor
本身是不用配置的,在/etc/supervisor/conf.d/
新增一个子进程的配置文件xxx.conf
,并reload一下supervisorctl
就可以了。以下是配置文件常用选项模板。1
2
3
4
5
6
7
8[program:XXX]
command=XXX #脚本执行命令(命令不能为守护进程)
directory=XXX #脚本目录
stdout_logfile=/var/log/XXX.log #日志输出
redirect_stderr=true #把 stderr 重定向到 stdout,默认 false
autostart=true #supervisor启动的时候是否随着同时启动,默认True
autorestart=true #当程序exit的时候,这个program不会自动重启,默认unexpected
stdout_logfile_maxbytes=10MB #stdout 日志文件大小,默认 50MB详细配置说明:
选项 | 简介 | 默认 | 必填 | 描述 |
---|---|---|---|---|
[program:xxx] | 子进程名称 | 无 | 是 | 这个就是咱们要管理的子进程了,: 后面的是名字,最好别乱写和实际进程,有点关联最好。这样的program我们可以设置一个或多个,一个program就是要被管理的一个进程 |
command | 脚本执行命令 | 无 | 是 | 这个就是我们的要启动进程的命令路径了,可以带参数 例子: /home/test.py -a 'hehe' 有一点需要注意的是,我们的command只能是那种在终端运行的进程,不能是守护进程。这个想想也知道了,比如说 command=service httpd start 。httpd这个进程被linux的service管理了,我们的supervisor再去启动这个命令这已经不是严格意义的子进程了。 |
process_name=%(program_name)s | 进程名 | 子进程名称 | 否 | 如果我们下面的numprocs参数为1的话,就不用管这个参数了,它默认值%(program_name)s 也就是上面的那个program冒号后面的名字,但是如果numprocs为多个的话,那就不能这么干了。想想也知道,不可能每个进程都用同一个进程名吧。 |
numprocs | 启动进程的数目 | 1 | 否 | 当不为1时,就是进程池的概念 |
directory | 运行目录 | 无 | 否 | 进程运行前,会前切换到这个目录 |
umask | 进程掩码 | none | 否 | 进程掩码 |
priority | 子进程启动关闭优先级 | 999 | 否 | 优先级低的,最先启动,关闭的时候最后关闭 |
autostart | 自启动 | true | 否 | 子进程将在supervisord启动后被自动启动 |
autorestart | 自动重启 | unexpected | 否 | 这个是设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动.如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的退出码的时候,才会被自动重启。当为true的时候,只要子进程挂掉,将会被无条件的重启 |
startsecs | 启动等待 | 1 | 否 | 这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了 |
startretries | 尝试启动次数 | 3 | 否 | 当进程启动失败后,最大尝试启动的次数。。当超过3次后,supervisor将把此进程的状态置为FAIL |
exitcodes | 退出码 | 无 | 否 | 和上面的的autorestart=unexpected 对应。。exitcodes里面的定义的退出码是expected的 |
stopsignal | 进程停止信号 | TERM | 否 | 以为TERM , HUP , INT , QUIT , KILL , USR1 , or USR2 等信号,当用设定的信号去干掉进程,退出码会被认为是expected |
stopwaitsecs | 停止信号等待时间 | 10 | 否 | 当我们向子进程发送stopsignal信号后,到系统返回信息给supervisord,所等待的最大时间。 超过这个时间,supervisord会向该子进程发送一个强制kill的信号。 |
stopasgroup | 停止进程组 | false | 否 | 这个东西主要用于,supervisord管理的子进程,这个子进程本身还有子进程。那么我们如果仅仅干掉supervisord的子进程的话,子进程的子进程有可能会变成孤儿进程。所以咱们可以设置可个选项,把整个该子进程的整个进程组都干掉。 设置为true的话,一般killasgroup 也会被设置为true。需要注意的是,该选项发送的是stop信号 |
killasgroup | 结束进程组 | false | 否 | 这个和上面的stopasgroup 类似,不过发送的是kill信号 |
user | 用户 | 无 | 否 | 如果supervisord是root 启动,我们在这里设置这个非root 用户,可以用来管理该program |
redirect_stderr | err重定向 | false | 否 | 如果为true,则stderr 的日志会被写入stdout 日志文件中 |
stdout_logfile | 日志路径 | 无 | 否 | 子进程的stdout 的日志路径,可以指定路径 ,AUTO ,none 等三个选项。设置为none 的话,将没有日志产生。设置为AUTO 的话,将随机找一个地方生成日志文件,而且当supervisord重新启动的时候,以前的日志文件会被清空。当 redirect_stderr=true 的时候,sterr 也会写进这个日志文件 |
stdout_logfile_maxbytes | 日志文件最大大小 | 50 | 否 | 日志文件最大大小 |
stdout_logfile_backups | 日志文件备份数 | 10 | 否 | 日志文件备份数 |
stdout_capture_maxbytes | capture管道的大小 | 0 | 否 | 这个东西是设定capture管道 的大小,当值不为0的时候,子进程可以从stdout 发送信息,而supervisor可以根据信息,发送相应的event。默认为0,为0的时候表达关闭管道 |
stdout_events_enabled | 触发event | false | 否 | 当设置为ture 的时候,当子进程由stdout 向文件描述符中写日志的时候,将触发supervisord发送PROCESS_LOG_STDOUT 类型的event |
stderr_logfile | stderr日志路径 | AUTO | 否 | 这个东西是设置stderr 写的日志路径,当redirect_stderr=true 。这个就不用设置了,设置了也是白搭。因为它会被写入stdout_logfile 的同一个文件中默认为AUTO ,也就是随便找个地存,supervisord重启被清空 |
stderr_logfile_maxbytes stderr_logfile_backups stderr_capture_maxbytes stderr_events_enabled |
stderr选项 | 无 | 否 | 和stdout 一样,就不详细说明了 |
environment | 环境变量 | 无 | 否 | 这个是该子进程的环境变量,和别的子进程是不共享的 |
supervisor配置
不过有的时候我们需要更改一些supervisor本身的配置,稍微解释下。
安装完成后默认的配置是这样的/etc/supervisor/supervisord.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf找不到这个文件用一下命令生成
1
echo_supervisord_conf > /etc/supervisord.conf
[unix_http_server]
这部分设置HTTP服务器监听的UNIX domain socket- file: 指向UNIX domain socket,即file=/var/run/supervisor.sock
- chmod:启动时改变supervisor.sock的权限
- [supervisord]
与supervisord有关的全局配置需要在这部分设置- logfile: 指向记录supervisord进程的log文件
- pidfile:pidfile保存子进程的路径
- childlogdir:子进程log目录设为AUTO的log目录
- [supervisorctl]
- serverurl:进入supervisord的URL, 对于UNIX domain sockets, 应设为 unix:///absolute/path/to/file.sock
- [rpcinterface:supervisor]
这个选项是给XML_RPC用的,当然你如果想使用supervisord或者web server 这个选项必须要开启的 [include]
如果配置文件包含该部分,则该部分必须包含一个files键- files:包含一个或多个文件,这里包含了/etc/supervisor/conf.d/目录下所有的.conf文件,可以在该目录下增加我们自己的配置文件,在该配置文件中增加[program:x]部分,用来运行我们自己的程序
还有一些高级选项我没试过,但找到了相关博客,先放上来,等试过了再写写
控制
两种方式控制supervisor,进入supervisor面板,或者直接运行命令
进入superviosrctl
1
supervisorctl
常用指令
1
2
3
4
5
6
7
8
9
10help [xxx] #不带参数为查看所有命令,带参数就是详解
start xxx #启动某个子进程
stop xxx #停止某个子进程
restart xxx #重启某个子进程
status #查看所有子进程状态
reload #重启supervisord
add #更新配置?好像是,不确定。
clear #清除日志
start/stop/restart... all #对所有子进程进行操作剩下的我感觉不太常用,以下是全部指令
1
2add clear fg open quit remove restart start stop update
avail exit maintail pid reload reread shutdown status tail version用到的时候再去查吧。
- 直接运行指令
1
supervisorctl xxx #xxx为上面的常用指令