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