supervisord管理服务进程

抄自

Mac使用专题

安装

brew install supervisor
brew install services

启动

brew services start supervisor

关闭

brew services stop supervisor

重启

brew services reload supervisor

supervisord 文件路径

/usr/local/bin/supervisord
/usr/local/opt/supervisor/bin/supervisord
/usr/local/Cellar/supervisor/4.2.4/libexec/bin/supervisord

supervisord.conf 文件路径

/usr/local/etc/supervisord.conf

supervisor 目录路径

/usr/local/opt/supervisor
$ cd /usr/local/opt/supervisor && ls
CHANGES.rst				bin
COPYRIGHT.txt				homebrew.mxcl.supervisor.plist
INSTALL_RECEIPT.json		homebrew.supervisor.service
README.rst					libexec

supervisord.ini 文件路径

/usr/local/etc/supervisor.d/*.ini

访问HTTP 管理界面,http://127.0.0.1:9001

vim supervisord.conf
# 在/etc/supervisord.conf中修改[inet_http_server]的参数
[inet_http_server]    ; 侦听在TCP上的socket
port=*:9001           ; 侦听的IP和端口
username=root         ; 连接的时候认证的用户,非必须设置
password=1234         ; 用户名对应的密码,可用明码和SHA加密,非必须设置

进程启动和守护的能力验证,http://127.0.0.1:8080

mkdir ~/example && mkdir -p ~/example/log && cd ~/example

echo 'pip install SimpleHTTPServer && python -m SimpleHTTPServer 8080' > test.sh

chmod +x test.sh

echo '
[program:test]
; 启动目录
directory = ~/example/
; 执行命令
command = sh ~/example/test.sh
; 随 supervisord 启动
autostart = true
; 程序启动 5s 内没有异常则认为是正常运行
startsecs = 5
; 程序异常退出后重新启动
autorestart = true
; 重试启动程序多少次
startretries = 3
; 默认使用当前用户执行应用
user = soulteary
; 需要手动创建目录
stdout_logfile = ~/example/log/supervisor.log
' > /usr/local/etc/supervisor.d/test.ini

brew services reload supervisor

安装

安装supervisor工具

yum install -y python-setuptools
easy_install supervisor

Ubuntu直接apt安装就可以了,自动生成/etc/supervisor目录和supervisord.conf配置文件

apt-get install supervisor

快速配置

创建默认配置文件

echo_supervisord_conf > /etc/supervisord.conf

启动默认配置,异常解决方案

supervisord -c /etc/supervisord.conf  # Centos
supervisord -c /etc/supervisor/supervisord.conf  # Ubuntu
supervisord -c /usr/local/etc/supervisord.conf  # Mac

检查进程

ps aux | grep supervisord

创建配置文件目录和日志

mkdir -pv /etc/supervisord.d/conf && mkdir -pv /etc/supervisord.d/log

CentOS系统的配置文件

vim /etc/supervisord.conf
[supervisord]
logfile=/var/log/supervisor/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=false

[include]
files = supervisord.d/conf/*.conf

Ubuntu的配置文件

vim /etc/supervisor/supervisord.conf
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700

[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[include]
files = /etc/supervisor/conf.d/*.conf

Mac的配置文件

vim /usr/local/etc/supervisord.conf

supervisord.conf 文件内容说明

# unix_http_server
;[unix_http_server]
;file=/var/run/supervisor.sock  ; socket文件的路径,用XML_RPC和supervisord进行通信,非必须设置
;chmod=0700                     ; 修改上面的那个socket文件的权限,非必须设置
;chown=escape:docker            ; 修改上面的那个socket文件的属组,非必须设置
;username=escape                ; 连接的时候认证的用户,非必须设置
;password=123456                ; 用户名对应的密码,可用明码和SHA加密,非必须设置

# inet_http_server
;[inet_http_server]    ; 侦听在TCP上的socket
;port=*:9001           ; 侦听的IP和端口
;username=root         ; 连接的时候认证的用户,非必须设置
;password=1234         ; 用户名对应的密码,可用明码和SHA加密,非必须设置

# supervisord
;[supervisord]                                ; 主要是定义supervisord服务端进程的一些参数
;logfile=/var/log/supervisor/supervisord.log  ; supervisord主进程的日志路径,非必须设置
;logfile_maxbytes=50MB                        ; 日志文件的最大的大小,超过则生成新的日志,非必须设置
;logfile_backups=10                           ; 日志文件保持的数量,默认为10个,非必须设置
;loglevel=info                                ; 日志级别,非必须设置
;pidfile=/var/run/supervisord.pid             ; supervisord服务的pid文件路径,非必须设置
;nodaemon=false                               ; 如果是true的话,supervisord进程将在前台运行,默认后台以守护进程运行
;umask=022                                    ; 进程创建文件的掩码
;user=escape                                  ; 以root启动之后,该用户可以对supervisord进行管理
;identifier=supervisor                        ; 多个supervisor且想调用XML_RPC统一管理,就需要为每个设置不同的标识符
;directory=/tmp                               ; 作为守护进程运行的时候会先切换到这个目录
;childlogdir=/var/log/supervisor              ; 当子进程日志路径为AUTO的时候,子进程日志文件的存放路径
;environment=KEY="value"                      ; 设置环境变量,会被子进程继承

# rpcinterface
;[rpcinterface:supervisor]  ; 给XML_RPC用的
;supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

# supervisorctl
;[supervisorctl]                            ; 主要是针对supervisorctl的一些配置
;serverurl=unix:///var/run/supervisor.sock  ; 注意这个是和前面的[unix_http_server]对应的
;username=root                              ; 用户名
;password=1234                              ; 密码
;prompt=mysupervisor                        ; 输入用户名密码时候的提示符
;history_file=~/.super_history              ; 参数和shell中的history类似

# include
;[include]
;files = /etc/supervisor/conf.d/*.conf      ; 读取配置文件的路径,支持匹配扩展

创建管理应用的配置

cd /etc/supervisor.d
cd /usr/local/etc/supervisor.d
vim program.ini

应用配置的ini文件说明

# program
;[program:theprogramname]      ; 必填选项,其格式为[program:应用名称]
;command=/bin/cat              ; 启动命令,可以使用参数,不能是守护进程
;process_name=%(program_name)s ; 当numprocs为1时,process_name=%(program_name)s;
                                 当numprocs>=2时,%(program_name)s_%(process_num)02d
;numprocs=1                    ; 启动的进程数量,默认为1个,类似进程池的概念
;directory=/tmp                ; 程序的执行目录
;umask=022                     ; 指定掩码,默认为None
;priority=999                  ; 指定优先级,值越高、最后启动、最先被关闭,默认值999
;autostart=true                ; 当supervisor启动时,程序将会自动启动
;startsecs=1                   ; 启动1秒后没有异常退出就当作已经正常启动
;startretries=3                ; 启动异常重试次数,超过这个次数就认为失败
;autorestart=unexpected        ; 程序异常退出后不会自动重启,true表示自动重启
;exitcodes=0,2                 ; 当退出码是0和2时,执行重启,默认值0和2
;stopsignal=HUP                ; 进程停止信号,默认为TERM,TERM/HUP/INT/QUIT/KILL等
;stopwaitsecs=10               ; 当向子进程发送stopsignal信号后,到系统返回信息给supervisord
                                 服务所等待的最大时间。超过这个时间,supervisord会向该子进程发
                                 送一个强制kill的信号
;stopasgroup=false             ; 主要用于supervisord管理的子进程,这个子进程本身还有子进程。
                                 那么我们如果仅仅干掉supervisord的子进程的话,子进程的子进程
                                 有可能会变成孤儿进程。设置这个选项,把整个该子进程的整个进程组
                                 都干掉。设置为true的话,一般killasgroup也会被设置为true的。
                                 需要注意的是,该选项发送的是stop信号
;killasgroup=false             ; 和上面的stopasgroup类似,不过发送的是kill信号
;user=escape                   ; 用哪个用户启动
;redirect_stderr=true          ; 如果为true,则stderr的日志会被写入stdout日志文件中,默认false
;stdout_logfile=/a/path        ; stdout日志文件路径
;stdout_logfile_maxbytes=1MB   ; stdout日志文件大小,默认50MB
;stdout_logfile_backups=10     ; stdout日志文件备份数,默认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日志文件路径
;stderr_logfile_maxbytes=1MB   ; stderr日志文件大小,默认50MB
;stderr_logfile_backups=10     ; stderr日志文件备份数,默认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"       ; 添加需要的环境变量
;serverurl=AUTO                ; override serverurl computation (childutils) |

信号

编号 信号名称 数字表示
1 SIGTERM supervisord 及其所有子进程都将关闭
2 SIGINT supervisord 及其所有子进程都将关闭
3 SIGQUIT supervisord 及其所有子进程都将关闭
4 SIGHUP supervisord 将关闭所有进程,重新载入配置文件并启动所有进程
5 SIGUSR2 supervisord 将关闭并重新打开主要活动日志和所有子日志文件
# 指定停止信号,默认为TERM
; [中断]: INT(类似于Ctrl+C)(kill -INT pid),退出后会将其写文件或日志(推荐)
; [终止]: TERM(类似于kill -TERM pid)
; [挂起]: HUP(类似于kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
; [从容停止]: QUIT(类似于kill -QUIT pid)
stopsignal=TERM

# 日常使用方式
[root@localhost ~] $ sudo supervisorctl signal hup app-test:*
信号名称 数字 说明
SIGHUP 1 终端挂起或控制进程终止。当用户退出 Shell 时,由该进程启动的所有进程都会收到这个信号,默认动作为终止进程。
SIGINT 2 键盘中断。当用户按下组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为终止进程。
SIGQUIT 3 键盘退出键被按下。当用户按下或组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为退出程序。
SIGFPE 8 发生致命的运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为 0 等所有的算法错误。默认动作为终止进程并产生 core 文件。
SIGKILL 9 无条件终止进程。进程接收到该信号会立即终止,不进行清理和暂存工作。该信号不能被忽略、处理和阻塞,它向系统管理员提供了可以杀死任何进程的方法。
SIGALRM 14 定时器超时,默认动作为终止进程。
SIGTERM 15 程序结束信号,可以由 kill 命令产生。与 SIGKILL 不同的是,SIGTERM 信号可以被阻塞和终止,以便程序在退出前可以保存工作或清理临时文件等。

supervisord分组

https://blog.csdn.net/qq_42517220/article/details/108624561

# 组配置模板
[group:lnmp]
programs=nginx-web,db-mysql,python-backend,confd  ; 指定组内成员
priority=999                                      ; 指定优先级,默认为999

服务配置模板,ini文件

[program:confd]
directory = /usr/local/bin
command = /usr/local/bin/confd -config-file /etc/confd/confd.toml
process_name=%(program_name)s
user = root
stopasgroup=true
killasgroup=true
autostart = true
startsecs = 5
autorestart = true
startretries = 3
stdout_logfile=/a/path
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stderr_logfile=/b/path
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=20
environment=PYTHONPATH="$PYTHONPATH:/path/to/somewhere"
# 环境变量需要通过%()s的方式使用
[program:example]
command=/usr/bin/example --loglevel=%(ENV_LOGLEVEL)s

服务启动

二进制启动

# 二进制启动
supervisord -c /etc/supervisord.conf

# 检查进程
ps aux | grep supervisord

设置开机启动及systemd方式启动

$ vim /etc/rc.d/init.d/supervisord
#!/bin/sh
#
# /etc/rc.d/init.d/supervisord
#
# Supervisor is a client/server system that
# allows its users to monitor and control a
# number of processes on UNIX-like operating
# systems.
#
# chkconfig: - 64 36
# description: Supervisor Server
# processname: supervisord

# Source init functions
. /etc/rc.d/init.d/functions

prog="supervisord"

prefix="/usr"
exec_prefix="${prefix}"
prog_bin="${exec_prefix}/bin/supervisord"
PIDFILE="/var/run/$prog.pid"

start() {
    echo -n $"Starting $prog: "
    daemon $prog_bin --pidfile $PIDFILE -c /etc/supervisord.conf
    [ -f $PIDFILE ] && success $"$prog startup" || failure $"$prog startup"
    echo
}

stop() {
    echo -n $"Shutting down $prog: "
    [ -f $PIDFILE ] && killproc $prog || success $"$prog shutdown"
    echo
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status $prog
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
        ;;
esac
# 设置开机启动及systemd方式启动
sudo chmod +x /etc/rc.d/init.d/supervisord
sudo chkconfig --add supervisord
sudo chkconfig supervisord on
sudo service supervisord start

命令使用

supervisorctl 命令

查看进程状态

# beepkg为配置文件[program:beepkg]里配置的值
supervisorctl status

启动某个进程

supervisorctl start beepkg

停止某一个进程

supervisorctl stop beepkg

重启某个进程

supervisorctl restart beepkg

启动所有属于名为groupworker这个分组的进程

supervisorctl start groupworker

停止所有属于名为groupworker这个分组的进程

supervisorctl stop groupworker

重动所有属于名为groupworker这个分组的进程

supervisorctl restart groupworker

停止全部进程

supervisorctl stop all

载入最新的配置文件

# 载入最新的配置文件
# 停止原有进程并按新的配置启动、管理所有进程
# 注意start、restart、stop都不会载入最新的配置文件
supervisorctl reload

根据最新的配置文件启动新配置或有改动的进程

# 根据最新的配置文件启动新配置或有改动的进程
# 注意,如果配置没有改动的进程不会受影响而重启
supervisorctl update

help

supervisorctl --help

supervisord 命令

help

supervisord --help

运行安全

开发人员尽力确保以 root 身份运行的 supervisord 进程不会导致意外的权限升级。但 supervisord 允许在其配置文件中的任意路径规范写入数据,允许任意路径选择可能会造成符号链接工具的漏洞。确保 supervisord 配置文件的权限安全,除此之外,确保 Python PATH 和标准库都有足够的文件权限保护。

服务状态

我们启动 supervisord 之后,可以查看进程的运行状态,所以必须事先知道 supervisord 到底有几种状态,对应状态代表着什么意思,之前的状态转移过程。

编号 进程状态 退出码 状态说明
1 STOPPED 0 该过程已经停止
2 STARTING 10 该过程正在启动
3 RUNNING 20 该过程正在运行
4 BACKOFF 30 该过程进入 STARTING 状态但退出太快导致无法进入 RUNNING 状态
5 STOPPING 40 该过程正在停止
6 EXITED 100 该过程退出 RUNNING 状态
7 FATAL 200 该过程无法成功启动
8 UNKNOWN 1000 该过程处于未知状态,通常为 supervisord 程序错误