进程管理工具--supervisor

作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai


Linux 的后台进程运行的方式有好几种,例如:nohup,screen等,具体方式可以查看这篇文章。但是,如果我们需要对一个服务程序进行可靠地在后台运行,我们就需要把它做成 daemon,最好还能监控进程状态,在意外结束时可以自动重启进程。

Supervisor 就是用 Python 开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台 daemon,并监控进程状态,异常退出时能自动重启。但是只能运行在 Unix-Like 的系统上,不能运行在 Windows 上。Supervisor 官方版目前只支持 Python 2.4 以上版本,但是还无法运行在 Python 3 上。

除此之外,supervisor 还能很友好的管理程序在命令行上输出的日志,可以将日志重定向到自定义的日志文件中,还能按文件大小对日志进行分割。

supervisor 是一个 C/S 系统,目前很多生产环境下的服务器都在使用 supervisor。

supervisor 的服务端称为 supervisord,主要负责在启动自身时启动管理的子进程,响应客户端的命令,重启崩溃或退出的子进程,记录子进程 stdout 和 stderr 输出,生成和处理子进程生命周期中的时间。可以在一个配置文件中配置相关参数,包括 supervisord 自身的状态,其管理的各个子进程的相关属性。配置文件一般位于 /etc/supervisord.conf 。

supervisor 的客户端称为 supervisorctl,它提供了一个类 shell 的接口(即命令行)来使用 supervisord 服务端提供的功能。通过 supervisorctl,用户可以连接到 supervisord 服务器进程,获得服务器进程控制的子进程的状态,启动和停止子进程,获得正在运行的进程列表。客户端通过 Unix 域套接字或者 TCP 套接字域服务端进行通信,服务器端具有身份凭证认证机制,可以有效提升安全性。当客户端和服务器位于同一台机器上时,客户端域服务器公用同一个配置文件 /etc/supervisord.conf,通过不同标签来区分两者的配置。

安装

supervisor 的安装很简单,我用的 Ubuntu 系统,直接使用如下命令就可以安装:

apt-get install supervisor
或者
pip install supervisor

配置文件说明

想要了解怎么配置需要管理的进程,只需要打开 supervisord.conf 就可以了,里面有很详细额注释消息。

接下来,我们来打开配置文件。

vi  /etc/supervisor/supervisord.conf

默认的配置文件是下面这样的.

; 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)
logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10           ; (num of main logfile rotation backups;default 10)


; 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

默认情况下,进程的日志文件达到 50 MB时,将进行分割,最多保留 10 个文件,当然这些配置也可以对每个进程单独配置。

进程的配置样例

我们写一个简单的例子,命名为 myapp.conf,文件的位置是 /etc/supervisor/conf.d/myapp.conf,如下:

; 设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名
[program:your_program_name] 
command=python server.py --port=9000
;numprocs=1                 ; 默认为1
;process_name=%(program_name)s   ; 默认为 %(program_name)s,即 [program:x] 中的 x
directory=/home/python/tornado_server ; 执行 command 之前,先切换到工作目录
user=oxygen                 ; 使用 oxygen 用户来启动该进程
; 程序崩溃时自动重启,重启次数是有限制的,默认为3次
autorestart=true            
startretries=3     ;启动失败自动重试次数,默认是3
redirect_stderr=true        ; 重定向输出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

当我们添加好配置文件之后,我们可以更新新的配置到 supervisord,如下:

supervisorctl update

我们顺便说一下 supervisor 的一些命令。

重新启动配置中的所有程序:

supervisorctl reload

启动某个进程(program_name = 你配置中写的程序名称)

supervisorctl start program_name

查看正在守候的进程

supervisorctl

停止某一进程(program_name = 你配置中写的程序名称)

supervisorctl stop program_name

重启某一进程(program_name = 你配置中写的程序名称)

supervisorctl restart program_name

停止全部进程

supervisorctl stop all

注意:用 stop 停止掉的进程,用 reload 或者 update 都不会自动重启。

以上这些命令,我们也可以通过终端来实现,输入命令 supervisorctl,就可以输入以下命令了:

  • help:查看帮助
  • status:查看程序状态
  • stop program_name:关闭指定的程序
  • start program_name:启动指定的程序
  • restart program_name:重启指定的程序
  • tail -f program_name:查看该程序的日志
  • update:重启配置文件修改过的程序

设置日志级别

loglevel 指定了日志的级别,用 Python 的 print 语句输出的日志是不会被记录到日志文件中的,需要搭配 Python 的 logging 模块来输出有指定级别的日志。

多个进程

按照官方文档的定义,一个 [program:x] 实际上是表示一组相同特征或同类的进程组,也就是说一个 [program:x] 可以启动多个进程。这组进程的成员是通过 numprocs 和 process_name 这两个参数来确定的,这句话什么意思呢,我们来看这个例子。

; 设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名
[program:foo] 
; 可以在 command 这里用 python 表达式传递不同的参数给每个进程
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; 执行 command 之前,先切换到工作目录
; 若 numprocs 不为1,process_name 的表达式中一定要包含 process_num 来区分不同的进程
numprocs=2                   
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen                 ; 使用 oxygen 用户来启动该进程
autorestart=true            ; 程序崩溃时自动重启
redirect_stderr=true        ; 重定向输出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

上面这个例子会启动两个进程,process_name 分别为 foo:foo_01 和 foo:foo_02。通过这样一种方式,就可以用一个 [program:x] 配置项,来启动一组非常类似的进程。

再介绍两个配置项 stopasgroup 和 killasgroup

; 默认为 false,如果设置为 true,当进程收到 stop 信号时,会自动将该信号发给该进程的子进程。如果这个配置项为 true,那么也隐含 killasgroup 为 true。例如在 Debug 模式使用 Flask 时,Flask 不会将接收到的 stop 信号也传递给它的子进程,因此就需要设置这个配置项。
stopasgroup=false             ; send stop signal to the UNIX process 

; 默认为 false,如果设置为 true,当进程收到 kill 信号时,会自动将该信号发给该进程的子进程。如果这个程序使用了 python 的 multiprocessing 时,就能自动停止它的子线程。
killasgroup=false             ; SIGKILL the UNIX process group (def false)

更详细的配置例子,可以参考如下:

;[program:theprogramname]
;command=/bin/cat              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999)
;autostart=true                ; start at supervisord start (default: true)
;autorestart=unexpected        ; whether/when to restart (default: unexpected)
;startsecs=1                   ; number of secs prog must stay running (def. 1)
;startretries=3                ; max # of serial start failures (default 3)
;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A="1",B="2"       ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

启动 supervisord

执行 supervisord 命令,将会启动 supervisord 进程,同时我们在配置文件中设置的进程也会相应启动。

# 使用默认的配置文件 /etc/supervisord.conf
supervisord
# 明确指定配置文件
supervisord -c /etc/supervisord.conf
# 使用 user 用户启动 supervisord
supervisord -u user

参考:
廖雪峰的官方网站
jobbole
cnblogs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值