Supervisor的作用与配置记录

已邀请:

Supervisor简介"margin:>

l 背景:

在一个分布式环境中,每台机器上可能需要启动和停止多个进程,使用命令行方式一个一个手动启动和停止非常麻烦,而且查看每个进程的状态也很不方便。如果有一个工具能够实现每台机器上多个进程的简单高效中心化管理将是非常方便的。于是Supervisord工具应运而生。与Supervisord类似的工具包括monit, daemontools和runit。

l 简介:

Supervisord的官网:http://supervisord.org。Supervisor是一个客户/服务器系统,它可以在类Unix系统中管理控制大量进程。Supervisor使用python开发,有多年历史,目前很多生产环境下的服务器都在使用Supervisor。

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

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

Supervisor也提供了一个web页面来查看和管理进程状态,这个功能用得人比较少。

安装supervisor

l 平台要求:

Supervisor可以运行在大多数Unix系统上,但不支持在Windows系统上运行。

Supervisor需要Python2.4及以上版本,但任何Python 3版本都不支持。

建议安装Supervisor 3.0及以上版本。

公司yum源没有找到,可用下面方式安装

1. 离线安装

cd /usr/local/src
wget https://pypi.python.org/packages/7b/17/88adf8cb25f80e2bc0d18e094fcd7ab300632ea00b601cbbbb84c2419eae/supervisor-3.3.2.tar.gz
tar -zxvf supervisor-3.3.2.tar.gz
cd supervisor-3.3.2
python setup.py install #本地python版本为python2.7
# python2.7 setup.py install #本地python版本为python3以上

2. 在线安装

安装easy_install       
sudo yum install python-setuptools-devel
安装Supervisor
easy_install supervisor
 生成配置文件
echo_supervisord_conf > /etc/supervisord.conf
 启动
supervisord -c /etc/supervisord.conf
ps aux | grep supervisord

下面以docker base镜像10.37.218.29:5000/suning/centos7.3_1611_supervisor:01已经安装了该软件,启动容器可看到supervisor进程

http://nccloud.yytimes.com/uploads/answer/20220927/f8e3639ffc21d5652785650dd7345af4.jpg

supervisor配置文件

cat /etc/supervisord.conf

配置文件如下(分号;表示注释):

; supervisor config file
[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file
;chmod=0700 ; socket file mode (default 0700)
;chown=nobody:nogroup ; socket file uid:gid owner
;username=user ; default is no username (open server)
;password=123 ; default is no password (open server)

;[inet_http_server] ; inet (TCP) server disabled by default
;port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
;username=user ; default is no username (open server)
;password=123 ; default is no password (open server)

[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
;umask=022 ; process file creation umask; default 022
;user=chrism ; default is current user, required if root
;identifier=supervisor ; supervisord identifier, default is 'supervisor'
;directory=/tmp ; default is not to cd during start
;nocleanup=true ; don't clean up tempfiles at start; default false
;childlogdir=/tmp ; 'AUTO' child log dir, default $TEMP
;environment=KEY="value" ; key value pairs to add to environment
;strip_ansi=false ; strip ansi escape codes in logs; def. false

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; should be same as in [*_http_server] if set
;password=123 ; should be same as in [*_http_server] if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available

;[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)
;startsecs=1 ; # of secs prog must stay up to be running (def. 1)
;startretries=3 ; max # of serial start failures when starting (default 3)
;autorestart=unexpected ; when to restart if exited after running (def: unexpected)
;exitcodes=0,2 ; 'expected' exit codes used with autorestart (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 (0 means none, 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 (0 means none, 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)

以上配置文件用到几个部分:

  • [unix_http_server]:这部分设置HTTP服务器监听的UNIX domain socket
    • file: 指向UNIX domain socket,supervisorctl 会使用
    • chmod:启动时改变supervisor.sock的权限,默认是0700
    • chown:socket文件的owner,格式:uid:gid
  • [inet_http_server]:HTTP服务器,提供web管理界面
    • port: Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
    • username:登录管理后台的用户名
    • password:登录管理后台的密码
  • [supervisord]:与supervisord有关的全局配置需要在这部分设置
    • logfile: 指向记录supervisord进程的log文件
    • logfile_maxbytes: 指定日志文件最大字节数,默认为50MB
    • logfile_backups: 要保存的logfile备份的数量
    • loglevel:日志级别
    • pidfile: pidfile保存子进程的路径,默认是supervisord的pid
    • nodaemon: 是否在前台启动,默认是false,即以 daemon 的方式启动
    • minfds: 可以打开的文件描述符的最小值,默认 1024
    • minprocs: 可以打开的进程数的最小值,默认 200
    • childlogdir:子进程log目录设为AUTO的log目录
  • [supervisorctl]:
    • serverurl:进入supervisord的URL, 对于UNIX domain sockets, 路径与unix_http_server部分的file一致
  • [include]:如果配置文件包含该部分,则该部分必须包含一个files键:
    • files:包含一个或多个文件,这里包含了/etc/supervisor/conf.d/目录下所有的.conf文件,可以在该目录下增加我们自己的配置文件,在该配置文件中增加[program:x]部分,用来运行我们自己的程序,如下:
  • [program:x]:配置文件必须包括至少一个program,x是program名称,必须写上,不能为空
    • command:包含一个命令,当这个program启动时执行
    • process_name:进程起一个名字,格式:%(program_name)s
    • numprocs:启动个数,默认1
    • directory:执行子进程时supervisord暂时切换到该目录
    • user:用哪个用户启动进程,默认是root
    • startsecs:进程从STARING状态转换到RUNNING状态program所需要保持运行的时间(单位:秒);启动后没有异常退出,就表示启动成功了
    • autorestart:程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
    • startretries:启动失败自动重试次数,默认是3
    • priority:进程启动优先级,默认999,值小的优先启动
    • redirect_stderr:如果是true,则进程的stderr输出被发送回其stdout文件描述符上的supervisord
    • stdout_logfile:将进程stdout输出到指定文件;stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
    • stdout_logfile_maxbytes:stdout_logfile指定日志文件最大字节数,默认为50MB,可以加KB、MB或GB等单位
    • stdout_logfile_backups:要保存的stdout_logfile备份的数量
    • stopasgroup:默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
    • killasgroup:默认为false,向进程组发送kill信号,包括子进程

子进程配置文件说明

给需要管理的子进程(程序)编写一个配置文件,放在/etc/supervisor.d/目录下,以.ini作为扩展名(每个进程的配置文件都可以单独分拆也可以把相关的脚本放一起)。如任意定义一个和脚本相关的项目名称的选项组(/etc/supervisord.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里面,才会被重启;如果为true将会无条件自动重启
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1

#脚本运行的用户身份
user = test

#日志输出
stderr_logfile=/tmp/blog_stderr.log
stdout_logfile=/tmp/blog_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true
#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20

子进程配置示例:

#说明同上
[program:test]
directory=/opt/bin
command=/opt/bin/test
autostart=true
autorestart=false
stderr_logfile=/tmp/test_stderr.log
stdout_logfile=/tmp/test_stdout.log
#user = test

Redis进程配置示例

[supervisord]
logfile = /var/log/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = true
nocleanup = true

[supervisorctl]
serverurl = unix:///tmp/supervisor.sock

[unix_http_server]
file=/tmp/supervisor.sock

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

[program:sshd]
command=/usr/sbin/sshd -D

[program:minion]
command=/usr/local/acm/core/minion -t minion
startretries=3
startsecs=10
directory=/usr/local/acm/core/
user=root
autorestart=true
killasgroup=true
stopasgroup=true

[program:initstart]
command=/bin/bash /script/init.sh
autorestart=true
startsecs=10
startretries=1
stopsignal=QUIT
redirect_stderr=false
stdout_logfile=/var/log/docker-out
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
stderr_logfile=/var/log/docker-err
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10

[eventlistener:monitor]
command=python /script/program_monitor.py
events=PROCESS_STATE_FATAL
stdout_logfile=/var/log/monitor-out
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
stderr_logfile=/var/log/monitor-err
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10

[program:zedis]
command=/opt/zedis/redis-server /opt/zedis/redis.conf
user=redisuser
autostart=true
;启动supervisord的时候会将该配置项设置为true的所有进程自动启动
stopasgroup=true
;使用supervisorctl停止zedis时,子进程也会一起停止
killasgroup=true
;向进程组发送kill信号,包括子进程
startsecs=10
;进程从STARING状态转换到RUNNING状态所需要保持运行10s时间
startretries=3
;启动失败自动重试次数,默认是3
autorestart=true
;进程停止后自动启动
stdout_logfile=/var/log/zedis-out
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
stderr_logfile=/var/log/zedis-err
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10

注:

Ø 因为无法监视后台进程,需要把Zedis前台运行(daemonize no),否则会识别不到Zedis启动,重试启动3次,日志提示6379已占用。

Ø 因为redis.conf指定了logfile,stdout_logfile并无内容输出;如果不指定redis.conf只是启动redis-server,日志会输出到stdout_logfile。

supervisor命令说明

supervisorctl status        //查看所有进程的状态

supervisord //启动supervisord
supervisorctl start all //启动supervisord管理的所有进程
supervisorctl stop all //停止supervisord管理的所有进程
supervisorctl restart all // 重启所有进程
supervisorctl stop zedis //停止zedis, name为[program:xx]中的xx
supervisorctl start zedis //启动zedis
supervisorctl restart zedis //重启zedis
supervisorctl update //配置文件修改后使用该命令加载新的配置
supervisorctl reload //重新加载配置文件并启动
supervisorctl shutdown //停止supervisord
http://nccloud.yytimes.com/uploads/answer/20220927/12858868edcb2a5798138677ae8de798.jpg

注:直接输入supervisorctl进入supervisorctl的shell交互界面,此时上面的命令不带supervisorctl可直接使用。

常见问题

l unix:///var/run/supervisor.sock no such file

问题描述:安装好supervisor没有开启服务直接使用supervisorctl报的错

解决办法:supervisord -c /etc/supervisord.conf

l command中指定的进程已经起来,但supervisor还不断重启

问题描述:command中启动方式为后台启动,导致识别不到pid,然后不断重启,这里使用的是elasticsearch,command指定的是$path/bin/elasticsearch -d

解决办法:supervisor无法检测后台启动进程的pid,而supervisor本身就是后台启动守护进程,因此不用担心这个

l 启动了多个supervisord服务,导致无法正常关闭服务

问题描述:在运行supervisord -c /etc/supervisord.conf之前,直接运行过supervisord -c /etc/supervisord.d/xx.conf导致有些进程被多个superviord管理,无法正常关闭进程。

"margin:>

解决办法:使用ps -fe | grep supervisord查看所有启动过的supervisord服务,kill相关的进程。

要回复问题请先登录注册