Supervisor是用Python写的一款应用程监控管理工具,能够启动,停止,重启死进程,提供web管理界面,XML-RPC接口及事件监听。通常我们写了一些脚本都不会带有daemon功能,而是加&或者nohub,screen什么的丢到后台去运行,同时使用corntab定时检测脚本是否存活,以便重新运行脚本。使用Supervisor可以将这些脚本,程序转为守护进程,自动重启它们;还可以监控机器的进程运行状况,输出警报等。
Supervisor只能运行于Python 2.x的环境,但子进程可以为其他任意程序,比如Python 3,PHP等。这里使用pip来安装
$ wget https://bootstrap.pypa.io/get-pip.py
$ python -V
$ sudo python get-pip.py
$ sudo pip install supervisor
生成配置文件及日志目录
$ sudo echo_supervisord_conf > /etc/supervisord.conf
$ mkdir /var/log/supervisor
$ chmod 655 /var/log/supervisor
启动supervisord
$ sudo supervisord -c /etc/supervisord.conf
$ supervisorctl
$ Server requires authentication
$ Username:user
$ Password:
$ supervisor> status
$ supervisor> help
default commands (type help <topic>):
=====================================
add exit open reload restart start tail
avail fg pid remove shutdown status update
clear maintail quit reread signal stop version
$ supervisor> quit
这里没有任何进程。以下为常用命令:
- supervisorctl stop program 停止某个进程
- supervisorctl start program 启动某个进程
- supervisorctl restart program 重启某个进程
- supervisorctl stop group 重启属于group分组的所有进程(start,restart同理)
- supervisorctl stop all 停止全部进程,注:start、restart、stop都不会载入最新的配置文件
- supervisorctl reload 载入最新配置文件,停止原有进程并按新配置启动进程
- supervisorctl update 根据最新配置文件,启动新配置或有改动的进程,没有改动的进程不受影响
编辑supervisord.conf启用web界面,账号密码为web及supervisorctl共用,必须更改
$ sudo vim /etc/supervisord.conf
#取消以下行的注释
[inet_http_server] ; inet (TCP) server disabled by default
port=*:9002 ; ip_address:port specifier, *:port for all iface
username=user ; default is no username (open server)
password=123 ; default is no password (open server)
#添加新应用qrd
[program:qrd]
command = /usr/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 qrd.wsgi
directory = /home/qrd/qrd/
user = root
autostart = true
autorestart = true
startsecs = 5
startretries = 3
stdout_logfile = /var/log/supervisor/qrd.log
stderr_logfile = /var/log/supervisor/qrd.log
重启使HTTP配置生效
ps aux | grep supervisord
kill
supervisord -c /etc/supervisord.conf
关于supervisord.conf配置项,命令释义可以参考这里。
- command 为要运行的脚本或程序
- directory 为脚本或程序运行时的工作目录
- user 为脚本或程序运行时的用户
- autostart 随supervisord启动
- startsecs 启动后等待时间,过了这个时间没起来就重新启动
- startretries 启动失败后重试的次数
- stdout_logfile,stderr_logfile 为输出日志
重新加载所有应用
$ supervisorctl
Server requires authentication
Username:user
Password:
supervisor> reload
Really restart the remote supervisord process y/N? y
Restarted supervisord
supervisor> status
qrd RUNNING pid 3861, uptime 0:00:22
可以看到定义的qrd程序已经起来了。如果qrd程序意外退出了,那么supervisord将会重启它。如果杀掉了supervisord,那么qrd对应的进程也将被杀死。也可以去web界面查看http://127.0.0.1:9002/
可以通过web页面来启动,停止进程,查看日志等。
再增加下Celery的Worker,Beat配置
; ==================================
; celery worker supervisor example
; ==================================
[program:qrdworker]
; Set full path to celery program if using virtualenv
command=/usr/bin/celery worker -A qrd --loglevel=INFO
; Alternatively,
;command=celery --app=your_app.celery:app worker --loglevel=INFO -n worker.%%h
; Or run a script
;command=celery.sh
directory=/home/qrd/qrd/
user=nobody
numprocs=1
stdout_logfile=/var/log/supervisor/qrdworker.log
stderr_logfile=/var/log/supervisor/qrdworker.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; Causes supervisor to send the termination signal (SIGTERM) to the whole process group.
stopasgroup=true
; Set Celery priority higher than default (999)
; so, if rabbitmq is supervised, it will start first.
priority=1000
; ================================
; celery beat supervisor example
; ================================
[program:qrdbeat]
; Set full path to celery program if using virtualenv
command=/usr/bin/celery -A qrd beat -l info -s /tmp/celerybeat-schedule
; remove the -A myapp argument if you aren't using an app instance
directory=/home/qrd/qrd/
user=nobody
numprocs=1
stdout_logfile=/var/log/supervisor/beat.log
stderr_logfile=/var/log/supervisor/beat.log
autostart=true
autorestart=true
startsecs=10
; Causes supervisor to send the termination signal (SIGTERM) to the whole process group.
stopasgroup=true
; if rabbitmq is supervised, set its priority higher
; so it starts first
priority=999
然后启用它们
supervisor> update
qrdbeat: added process group
supervisor> status
qrd RUNNING pid 4468, uptime 0:03:49
qrdbeat BACKOFF Exited too quickly (process log may have details)
qrdworker RUNNING pid 4469, uptime 0:03:49
查看下进程
$ sudo ps aux | grep python
root 1038 0.0 3.1 562392 15720 ? Ssl 01:49 0:01 /usr/bin/python -Es /usr/sbin/tuned -l -P
root 3992 0.1 3.0 222124 15224 ? Ss 03:49 0:00 /bin/python /bin/supervisord -c /etc/supervisord.conf
root 3993 0.3 3.8 211868 19296 ? S 03:49 0:00 /usr/local/python3/bin/python3.6 /usr/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 qrd.wsgi
root 3996 0.3 6.9 264048 34780 ? S 03:49 0:00 /usr/local/python3/bin/python3.6 /usr/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 qrd.wsgi
root 3998 0.3 6.9 264056 34784 ? S 03:49 0:00 /usr/local/python3/bin/python3.6 /usr/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 qrd.wsgi
root 3999 0.4 6.9 264024 34784 ? S 03:49 0:00 /usr/local/python3/bin/python3.6 /usr/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 qrd.wsgi
root 4014 0.0 0.1 112660 976 pts/0 R+ 03:50 0:00 grep --color=auto python
除了program标签,Supervisor也支持group标签,用来启动一系列的program,比如先启动数据库,再启动web服务器。
Supervisor也可以用来管理PHP进程,比如使用 Supervisor 管理 Laravel 队列进程。
Docker官方推荐一个docker容器只运行一个服务,如果你想启动多个脚本或程序,可以使用Supervisor会更简单点。
如果需要Supervisor开启启动,可以使用GitHub上的脚本和配置。CentOS 7上可以配置为service,由systemctl来管理:
$ sudo vim /etc/systemd/system/supervisord.service
内容如下:
# supervisord service for systemd (CentOS 7.0+)
# by ET-CS (https://github.com/ET-CS)
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
然后启用
$ sudo systemctl enable supervisord.service
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /etc/systemd/system/supervisord.service.
$ sudo systemctl start supervisord.service
$ sudo ps aux | grep python
虽然supervisorctl及web界面都只能管理本机,但是Supervisor提供了XML-RPC接口,可以获取进程运行信息,因此诞生了许多监控平台,以便监控服务器集群的进程的运行状况。
Supervisor还提供了event listener配置,在这里Supervisor将会通知脚本其他进程的运行状态变更的事件,可以用来发送警报监控等。
参考链接:
使用Supervisor3.2.1基于Mac10.10.3对系统进程进行管理
supervisor的配置浅析
Python 进程管理工具 Supervisor 使用教程
Supervisor进程监护使用指南
supervisord 的 XML-RPC API 使用说明
Supervisor Event Listener
Dockerizing Nginx and SSH using Supervisord