Linux 后台任务进程管理工具supervisor的使用
前言:很早就想写篇关于supervisor这个后台任务管理工具了,工作中也一直在用到,但是也只是简单的参数复制复制,这次想把官方文档重要的地方翻译一下,然后结合自己实际工作的例子结合演示
官方文档地址: http://supervisord.org/introduction.html#overview
原地址: https://blog.csdn.net/wgPython/article/details/103743321 现在已经迁移过来
一.Supervisor 介绍
首先介绍下supervisor是什么:
原文:Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems
翻译:supervisor是一个客户端/服务端系统,它允许用户在类Unix系统上控制多个进程
白话:说白了就是在Linux/Mac os等类Unix系统上管理后台任务进程的。
把程序放在后台执行,不至于关掉控制台,程序就不执行了。
注意
:supervisor是不支持Windows系统
的,原话Supervisor will not run at all under any version of Windows.
同样的功能,Linux也有命令也有把程序放到后台运行的方式
- setsid
// 用法
setsid command
// 例如
setsid /home/xxx.sh
或者
setsid python a.py
- nohup
// 最简单用法 还可以输出日志等 (意思是把`command`命令启动的服务托管到后台,然后把输出内容保存到app.log里面)
nohup command > app.log 2>&1 &
尽管有这么多后台运行方式,但是功能和可靠性是没有supervisor强大的。
http://supervisord.org/introduction.html#features
比如我所需要的,异常退出重启,日志输出管理,多任务进程等等
还可以自定义web控制面板监控
二.安装篇
由于supervisor是Python写的,所以需要依赖Python环境: Supervisor is intended to work on Python 3 version 3.4 or later and on Python 2 version 2.7.
Python3版本>=3.4 或者 Python2.7版本
类Unix系统一般是默认安装了Python2.7的,所以可以直接用pip(Python包管理工具)安装
# centos系统可以使用yum安装
sudo yum install supervisor
# 或者pip在线安装 ⚠️直接默认全局安装Python2环境
pip install supervisor
# 或者pip离线包安装 这里不介绍
相关文件说明
/etc/supervisord.conf # supervisord配置文件,一般不用设置
/etc/supervisord.d/ # 任务配置文件目录,需要管理的后台任务得放在这个文件夹下,且文件后缀得以ini结尾
# 可以去 /etc/supervisord.conf 配置最后一行修改读取配置文件的后缀
后台运行服务
# 启动
sudo service supervisord start
# 重启
sudo systemctl restart supervisord
# 有次我程序一直记载启动异常,报错不记得了,就是启动不了我的任务
我搜到了关于解决我那个问题解决方式:
https://github.com/Supervisor/supervisor/issues/121#issuecomment-25202472
三.使用
e.g. 部署Flask 应用来做例子, 顺便介绍下gunicorn的使用
我比较喜欢以这种方式部署:gunicorn + nginx + supervisor来部署
简单介绍下gunicorn
比如我新建一个文件叫 wsgi.py (tip:名字可自己随意取)
from flask import Flask
application = Flask(__name__) # 我就故意不取变量名为 app
@application.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
application.run()
然后我用gunicorn服务的启动命令就是, (注意我使用的是pipenv包管理)
pipenv run gunicorn --workers=4 --bind=0.0.0.0:8000 wsgi:application
参数 | 解释 |
---|---|
--workers=4: | 可简写成-w=4 表示4个worker,可根据服务器配置调高 |
--bind=0.0.0.0:8000 | 可简写-b=ip:port 指定ip和端口,写成0.0.0.0就可以外网通过ip访问(一般写成127.0.0.1, 由nginx转发) 默认127.0.0.0:8000 |
wsgi:application | 表示wsgi表示应用文件名,application 表示应用里面取的对象名 |
正篇使用
使用supervisor管理 gunicorn 应用。(尽管gunicorn 参数-D可以托管到后台)
# 切换目录
cd /etc/supervisord.d/
# 新建后台任务文件 如 flask.ini # 必须得以ini结尾
[program:app] ; app表示任务名称,在后面supervisor控制面板里面会看到
command=pipenv run gunicorn app:app -w 8 ; 执行的程序命令
directory=/home/project ; 程序文件目录
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
autostart=true ; supervisord 启动的时候也自动启动
;environment=变量名1="变量值1",变量名2="变量值2" ; 设置环境变量
;user=root ; 执行的任务的用户,可不用指定
redirect_stderr=true
stdout_logfile=/home/project/logs/app.log # 自定义的输出日志文件, 默认50M,多了会自动分割文件
- .ini注意配置文件最好不要加注释, 如图这是一个gunicorn 启动配置示例:(取的绝对路径)
[program:flask]
command=/root/.local/share/virtualenvs/xxx-zoz4Kxle/bin/gunicorn app:app -w 8
directory=/xxx/project
autostart=true
autorestart=true
stopsignal=QUIT
redirect_stderr=true
stdout_logfile=/xxx/project/logs/flask.log
- 还可以参考 Flask 狗书作者miguelgrinberg的github配置示例 https://github.com/miguelgrinberg/microblog/blob/master/deployment/supervisor/microblog.conf
- 有一种情况: 比如我同一个命令,要执行多次;
好比我使用的 rq https://github.com/rq/rq 这个简单的消息队列, 我要在一个服务器上启多个服务,所以就直接开多个进程就行了。
# 直接在参数里面加这几行
process_name=%(program_name)s_%(process_num)02d ;多进程名称设置不同
numprocs=4 ;同时启动多个进程
stopasgroup=true # 一起kill掉子进程
killasgroup=true # 多个进程一起kill
四 管理supervisor子任务
可以使用 supervisorctl
命令在控制面板查看当前运行的任务
# 控制面板操作
supervisor> restart app # 重启任务 app任务名, 任务文件.ini中设置的 [program:app]
supervisor> stop app # 停止任务
supervisor> update app # 启动app
supervisor> status app # 查看状态
supervisor> exit # 退出
supervisor> help # 一共这么多命令
default commands (type help <topic>):
=====================================
add clear fg open quit remove restart start stop update
avail exit maintail pid reload reread shutdown status tail version
- 也可以在命令行运行
# 比如你在 /etc/supervisord.d/ 目录下
先增加了一个flask.ini任务,
后面又新增scrapy.ini 任务
# 可以在命令行使用 update更新子任务
> sudo supervisorctl update # 默认更新全部 后面加 任务文件名 启动特定任务