Linux工具篇supervisor进程管理器

13次阅读

共计 5168 个字符,预计需要花费 13 分钟才能阅读完成。

概述

项目中遇到有些脚本需要通过后台进程运行,保证不被异常中断,除了通过 nohup、&、screen 以外,更推荐的方法就是用 Supervisor。

Supervisor 是用 Python 开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台 daemon,并监控进程状态,异常退出时能自动重启。它是通过 fork/exec 的方式把这些被管理的进程当作 supervisor 的子进程来启动,这样只要在 supervisor 的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor 还提供了一个功能,可以为 supervisord 或者每个子进程,设置一个非 root 的 user,这个 user 就可以管理它对应的进程。

安装

1:easy_install 安装:easy_install supervisor

2:pip 安装:pip install supervisor

3:Debian / Ubuntu 可以直接通过 apt 安装:apt-get install supervisor

配置

  1. 通过 apt-get install 安装后,supervisor 的配置文件在:

    /etc/supervisor/supervisord.conf 

supervisor 的配置文件默认是不全的,不过在大部分默认的情况下,上面说的基本功能已经满足。而其管理的子进程配置文件在:

/etc/supervisor/conf.d/*.conf
  1. 通过 easy_install 或者 pip 安装的,配置文件不存在,需要自己导入。

运行 echo_supervisord_conf 打印出一个配置文件的样本,样本说明可以看 supervisor(一)基础篇的详细说明,要是设置样本为一个配置文件则:

1:运行 echo_supervisord_conf,查看配置样本:echo_supervisord_conf

2:创建配置文件:echo_supervisord_conf > /etc/supervisord.conf

配置子进程配置文件,可以直接在 supervisor 中的 [program:theprogramname] 里设置。

;[program:theprogramname]      ; 这个就是咱们要管理的子进程了,":" 后面的是名字,最好别乱写和实际进程
                                有点关联最好。这样的 program 我们可以设置一个或多个,一个 program 就是
                                要被管理的一个进程
;command=/bin/cat              ; 这个就是我们的要启动进程的命令路径了,可以带参数
                                例子:/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 时,就是进程池的概念,注意 process_name 的设置
                                 默认为 1。。非必须设置
;directory=/tmp                ; 进程运行前,会前切换到这个目录
                                 默认不设置。。。非必须设置
;umask=022                     ; 进程掩码,默认 none,非必须
;priority=999                  ; 子进程启动关闭优先级,优先级低的,最先启动,关闭的时候最后关闭
                                 默认值为 999。。非必须设置
;autostart=true                ; 如果是 true 的话,子进程将在 supervisord 启动后被自动启动
                                 默认就是 true。。非必须设置
;autorestart=unexpected        ; 这个是设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected
                                 和 true。如果为 false 的时候,无论什么情况下,都不会被重新启动,如果为 unexpected,只有当进程的退出码不在下面的 exitcodes 里面定义的退 
                                 出码的时候,才会被自动重启。当为 true 的时候,只要子进程挂掉,将会被无
                                 条件的重启
;startsecs=1                   ; 这个选项是子进程启动多少秒之后,此时状态如果是 running,则我们认为启
                                 动成功了
                                 默认值为 1。。非必须设置
;startretries=3                ; 当进程启动失败后,最大尝试启动的次数。。当超过 3 次后,supervisor 将把
                                 此进程的状态置为 FAIL
                                 默认值为 3。。非必须设置
;exitcodes=0,2                 ; 注意和上面的的 autorestart=unexpected 对应。。exitcodes 里面的定义的
                                 退出码是 expected 的。;stopsignal=QUIT               ; 进程停止信号,可以为 TERM, HUP, INT, QUIT, KILL, USR1, or USR2 等信号
                                  默认为 TERM。。当用设定的信号去干掉进程,退出码会被认为是 expected
                                  非必须设置
;stopwaitsecs=10               ; 这个是当我们向子进程发送 stopsignal 信号后,到系统返回信息
                                 给 supervisord,所等待的最大时间。超过这个时间,supervisord 会向该
                                 子进程发送一个强制 kill 的信号。默认为 10 秒。。非必须设置
;stopasgroup=false             ; 这个东西主要用于,supervisord 管理的子进程,这个子进程本身还有
                                 子进程。那么我们如果仅仅干掉 supervisord 的子进程的话,子进程的子进程
                                 有可能会变成孤儿进程。所以咱们可以设置可个选项,把整个该子进程的
                                 整个进程组都干掉。设置为 true 的话,一般 killasgroup 也会被设置为 true。需要注意的是,该选项发送的是 stop 信号
                                 默认为 false。。非必须设置。。;killasgroup=false             ; 这个和上面的 stopasgroup 类似,不过发送的是 kill 信号
;user=chrism                   ; 如果 supervisord 是 root 启动,我们在这里设置这个非 root 用户,可以用来
                                 管理该 program
                                 默认不设置。。。非必须设置项
;redirect_stderr=true          ; 如果为 true,则 stderr 的日志会被写入 stdout 日志文件中
                                 默认为 false,非必须设置
;stdout_logfile=/a/path        ; 子进程的 stdout 的日志路径,可以指定路径,AUTO,none 等三个选项。设置为 none 的话,将没有日志产生。设置为 AUTO 的话,将随机找一个地方
                                 生成日志文件,而且当 supervisord 重新启动的时候,以前的日志文件会被
                                 清空。当 redirect_stderr=true 的时候,sterr 也会写进这个日志文件
;stdout_logfile_maxbytes=1MB   ; 日志文件最大大小,和 [supervisord] 中定义的一样。默认为 50
;stdout_logfile_backups=10     ; 和 [supervisord] 定义的一样。默认 10
;stdout_capture_maxbytes=1MB   ; 这个东西是设定 capture 管道的大小,当值不为 0 的时候,子进程可以从 stdout
                                 发送信息,而 supervisor 可以根据信息,发送相应的 event。默认为 0,为 0 的时候表达关闭管道。。。非必须项
;stdout_events_enabled=false   ; 当设置为 ture 的时候,当子进程由 stdout 向文件描述符中写日志的时候,将
                                 触发 supervisord 发送 PROCESS_LOG_STDOUT 类型的 event
                                 默认为 false。。。非必须设置
;stderr_logfile=/a/path        ; 这个东西是设置 stderr 写的日志路径,当 redirect_stderr=true。这个就不用
                                 设置了,设置了也是白搭。因为它会被写入 stdout_logfile 的同一个文件中
                                 默认为 AUTO,也就是随便找个地存,supervisord 重启被清空。。非必须设置
;stderr_logfile_maxbytes=1MB   ; 这个出现好几次了,就不重复了
;stderr_logfile_backups=10     ; 这个也是
;stderr_capture_maxbytes=1MB   ; 这个一样,和 stdout_capture 一样。默认为 0,关闭状态
;stderr_events_enabled=false   ; 这个也是一样,默认为 false
;environment=A="1",B="2"       ; 这个是该子进程的环境变量,和别的子进程是不共享的
;serverurl=AUTO                ; 

配置参考

/etc/supervisor/conf.d/test.conf
# 项目名
[program:blog]
# 脚本目录
directory=/opt/bin
#脚本执行命令
command=/usr/bin/python /opt/bin/test.py
#supervisor 启动的时候是否随着同时启动,默认 True
autostart=true
#当程序 exit 的时候,这个 program 不会自动重启, 默认 unexpected
#设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected 和 true。如果为 false 的时候,无论什么情况下,都不会被重新启动,如果为 unexpected,只有当进程的退出码不在下面的 exitcodes 里面定义的
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是 running,则我们认为启动成功了。默认值为 1
startsecs=1
#日志输出 
stderr_logfile=/tmp/blog_stderr.log 
stdout_logfile=/tmp/blog_stdout.log 
#脚本运行的用户身份 
user = zhoujy 
#把 stderr 重定向到 stdout,默认 false
redirect_stderr = true
#stdout 日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20M
#stdout 日志文件备份数
stdout_logfile_backups = 20

[program:easyswoole]
directory=/home/wwwroot/easyswoole
command=php easyswoole start
autorestart=true
startsecs=1
stderr_logfile=/tmp/supervisord_easyswoole.log 
stdout_logfile=/tmp/supervisord_easyswoole.log  
user = root 
redirect_stderr = true
stdout_logfile_maxbytes = 20M
stdout_logfile_backups = 20

# 以下两个要加,否则会报.ini file does not include supervisord section
[supervisord]
[supervisorctl]

使用

运行

1)apt-get install 安装的 supervisor 直接可以通过 /etc/init.d/supervisor 运行:

/etc/init.d/supervisor start

2)通过 easy_install 安装的 supervisor 运行 supervisord 运行:

# 注意,要守护的进程不要单独启动,直接执行 supervisor 即可
supervisord -c /etc/supervisord.conf

编辑配置后,可以通过 supervisorctl update 生效

web 界面

[inet_http_server]
port=0.0.0.0:9002
username=user
password=123

子进程管理

# 有多少子进程
supervisorctl status

# easyswoole 进程
supervisorctl stop easyswoole
supervisorctl start easyswoole

# 全部
supervisorctl stop all
supervisorctl start all

参考资料

Supervisor 官方文档

Supervisor(一)基础篇

Supervisor(二)eventevent”)

Supervisor(三)xml_rpcxml_rpc”)

正文完
 0