以python为例,当我们用flask
发布一个服务时,希望这个服务可以一直运行,然而,服务可能会由于某些原因而挂掉。我希望有这样一种方法,可以监控这个服务的进程,如果挂掉,则自动重启。
supervisor
就是一种很好的实现这种效果的工具。
1、什么是supervisor
supervisor
的项目地址在这里,官方文档在这里。按照我的理解,supervisor
提供了一种监控功能:它能够时刻监视其所管理的服务的状态,如果状态出现异常,那么就可以按照预定的规则进行重启。
需要注意的是,supervisor
只能在Linux、macOS等类UNIX系统上运行,在任何版本的Windows系统上都无法运行。
2、supervisor
的安装与使用
安装:
pip install supervisor
安装完成后,执行以下命令以在特定位置生成配置文件:
echo_supervisord_conf > /etc/supervisord.conf
注意,上述命令需要拥有root权限才可以运行;如果没有root权限,参考这里进行解决。
⚠️ 2021年4月29日补充:
上述echo_supervisord_conf
命令在某些情况下可能并不能在任何目录都起作用,这时可以切换到supervisor的安装目录下执行上述命令(通过pip show supervisor
打印的Location字段的值获取安装位置)。
通过配置文件,可以向supervisor
添加需要管理的程序以及管理方式。配置文件的格式与python中ConfigParser解析的文件格式相同,由section以及key-value对组成。配置文件中可设置的内容很多,这里只挑其中关键的一部分进行说明:
[unix_http_server]
; supervisor从这里指定的套接字来监听HTTP请求
file=/python-projects/supervisor-gunicorn-flask/supervisor/supervisor.sock
[supervisord]
; 记录supervisord程序活动日志的文件
logfile=/python-projects/supervisor-gunicorn-flask/supervisor/supervisord.log
; 最大的日志文件大小
logfile_maxbytes=50MB
; 超过日志最大容量,将会备份,这里控制备份日志的数量
logfile_backups=10
; 日志等级
loglevel=info
; supervisord程序的进程号
pidfile=/python-projects/supervisor-gunicorn-flask/supervisor/supervisord.pid
; 设置为守护进程
nodaemon=false
; 控制要不要将日志打印到标准输出
silent=false
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
; 用于访问supervisord服务以对其进行管理的套接字
serverurl=unix:///python-projects/supervisor-gunicorn-flask/supervisor/supervisor.sock
[program:gunicorn]
; 启动程序的命令
command=gunicorn -w 4 -b 0.0.0.0:5000 my_app:app
; 脚本的位置,在这个例子中,就是my_app.py的位置
directory=/python-projects/supervisor-gunicorn-flask
; 是否在启动supervisord的时候启动程序
autostart=true
; 当supervisord程序启动后,等待多少秒后才启动目标程序。这个参数在目标程序重启时仍有效。
startsecs=1
; 当管理的程序终止时是否自动重新启动
autorestart=true
; 标准输出日志的位置,目录必须事先创建,文件不必创建
stdout_logfile=/python-projects/supervisor-gunicorn-flask/logs/stdout.log
; 标准错误日志的位置,目录必须事先创建,文件不必创建
stderr_logfile=/python-projects/supervisor-gunicorn-flask/logs/stderr.log
配置完上述参数后,运行以下命令进行启动:
supervisord -c /etc/supervisord.conf
⚠️2021年4月29日更新:
如果想要通过gunicorn
的配置文件启动,可以将上述command
的值设置成gunicorn -c gunicorn_cfg.py my_app:app
,然后在gunicorn_cfg.py
中配置相关信息。如果使用这种方法,注意不要将gunicorn
配置为守护进程,这将导致supervisor
失效:虽然可以启动服务,但在服务异常终止时无法重启,暂时不明白为什么会这样。
3、supervisorctl
与supervisord
的关系
supervisord
是直接管理目标程序的,而supervisorctl
则是管理supervisord
的。它们共用一个配置文件,即上一部分提到的/etc/supervisord.conf
文件。
说明:
supervisord.conf
文件配置不合法时,会导致supervisorctl
命令失效。
我遇到一个情况,即使修改了配置文件为合法的,也无法使supervisorctl
命令有效,最后的解决方案是,将supervisord
服务停止,删除配置文件,然后重新生成并修改配置。