supervisor 是一个Python开发的、通用的进程管理程序。当程序中断时,supervisor能自动重启它,不再需要程序员或系统管理员自己编写代码来控制。
supervisor要求管理程序是非daemon程序,supervisor会把程序转成daemon程序,因此若使用supervisor来管理进程,进程需要以非daemon的方式启动。
附上supervisor官网 点此链接进入官网
[inet_http_server]
板块里面。本章基于阿里云服务器,Ubuntu20.04系统进行搭建。系统默认Python版本为Python 3.8.10,使用virtualenvs
搭建的虚拟环境,名称为django
。
管理进程主要有Nginx代理和基于后端Django的uWSGI服务。
在Python默认的版本下进行安装,不安装在虚拟环境下,
pip3 install supervisor
输入以下命令,出现以下界面说明安装成功!
echo_supervisord_conf
在etc目录下生成supervisord_conf配置文件
echo_supervisord_conf > /etc/supervisord.conf
输入命令后可以进入/etc目录下,查看是否存在该文件,或者直接使用cat进行查看也行。
网上有的配置是将所有需要管理的进程都放在了supervisor.conf配置文件里面了,这里不推荐使用此方法,管理起来太过于繁琐,本章是将需要管理的进程服务分别放在了同一个目录下不同的.ini文件中,这样既能方便配置不同的需求也可以及时查看或更改配置的进程服务。
在/ect目录下创建supervisord.d目录,并且进入该目录分别创建nginx.ini和uwsgi.ini子进程配置文件。
#创建supervisord.d目录
mkdir /etc/supervisord.d -p
#进入该目录下
cd supervisord.d
#创建子进程配置文件
touch nginx.ini
touch uwsgi.ini
vi nginx.ini
粘贴一下内容到nginx.ini配置文件中
[program:nginx]
#command为命令行,类似于linux的命令
command=/usr/sbin/nginx -g 'daemon off;'
# 打开的目录,nginx的配置文件,即也可以是项目所在目录
directory=/etc/nginx
#如果是true的话,子进程将在supervisord启动后被自动启动,默认就是true,非必须设置
autostart=true
#这个是设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的退 出码的时候,才会被自动重启。当为true的时候,只要子进程挂掉,将会被无条件的重启
autorestart=true
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了
startsecs=1
# 当进程启动失败后,最大尝试启动的次数。。当超过3次后,supervisor将把此进程的状态置为FAIL
stopwaitsecs=2
#脚本运行的用户身份
user=root
#日志输出
stderr_logfile=/home/kql/project/logs/blog_stderr.log
stdout_logfile=/home/kql/project/logs/blog_stdout.log
#如果为true,则stderr的日志会被写入stdout日志文件中默认为false,非必须设置
redirect_stderr=true
#日志文件最大大小,和[supervisord]中定义的一样。默认为50
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
输入:wq
保存退出!
这里有个坑,语法: daemon on | off
缺省值: on
Do not use the “daemon” and “master_process” directives in a production mode, these options are mainly used for development only. You can use daemon off
大意:在生产环境中 daemon 和 master_process 配置均不可使用,仅用于开发测试。为了方便开发测试 Nginx 的 daemon 参数默认值为 on。如果大家使用 Docker 看过 Nginx 镜像的 Dockerfile 你就明白这个,所以在配置nginx.ini文件中一定要加入daemon onoff
其次配置uWSGI进程,uwsgi进程是运行在django虚拟环境下的,如果直接使用,是启动的不了的。从网上看到很多帖子,有的是直接在command命令行中直接写入uwsgi所在虚拟环境的具体目录下,本章使用了一个简单的方法可以直接调用它,即使用linux的软连接创建uwsgi快捷命令。
所以先创建uwsgi的软连接。我的uwsgi所在的目录在/root/.virtualenvs/django/bin/
下,因此输入一下命令可以直接创建。
ln -s /root/.virtualenvs/django/bin/uwsgi /usr/local/bin/uwsgi
之后进入supervisord.d目录下编辑uwsgi.ini即可。
vi uwsgi.ini
复制以下内容至uwsgi.ini配置文件下
[program:wsgi]
#前面的目录是uwsgi创建的软连接所在目录,当然,也可以不写,直接写入uwsgi也可以运行,--ini后面的目录是 是我的项目下的uwsgi.ini配置文件所在的路径。
command=/usr/local/bin/uwsgi --ini /home/kql/project/backdjango/uwsgi.ini --die-on-term
#directory=/etc/nginx
autostart=true
autorestart=true
startsecs=1
stopwaitsecs=2
#脚本运行的用户身份
user=root
#日志输出
stderr_logfile=/home/kql/project/logs/plantool_stdout.log
stdout_logfile=/home/kql/project/logs/plantool_err.log
#把stderr重定向到stdout,默认为false
redirect_stderr=true
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
CPU使用率100%问题
在Linux里面看下进程
ps aux | less
发现占用cpu的是一堆uwsgi进程,uwsgi配置文件里processes填的是4
按道理最多只有4个uwsgi进程,但是这有十几个,每个占用率有百分之十几
网上说法:
python+supervisor+uwsgi跑web程序时出现uwsgi defunct进程的cpu达到100%问题
这个问题的原因是supervisor中进程退出,而重启进程时的处理有问题 详细情况可以看
https://github.com/unbit/uwsgi/issues/296
问题解决的办法是在uwsgi的配置文件中添加die-on-term = true参数 或者在命令行参数中添加–die-on-term参数
本人暂时加了这个参数,不确定有没有用
使用 kill -f uwsgi -9
命令
杀掉之前已经存在的uwsgi进程,一下子cpu占用率就下去了。
进入/etc目录下修改supervisor.conf文件,
将以下代码更改为
;[include]
;files = relative/directory/*.ini
[include]
files = /etc/supervisord.d/*.ini
意思是管理的子进程配置文件所在的目录路径。*.ini
意思是所有的.ini文件。
然后将以下代码取消注释,配置用户名、密码和端口号。
[inet_http_server]
#所有ip都可访问9001端口管理进程
port=*:9001
#web界面登入的用户名
username=admin
#web界面登入的密码
password=123123
保存输入:wq退出!
使用以下命令启动supervisor
supervisord -c /etc/supervisord.conf
启动成功后可以使用以下命令来查看nginx和uwsgi是否启动成功
ps -ef | grep nginx
ps -ef | grep uwsgi
ps -ef | grep supervisord
supervisorctl status #查看所有子进程服务状态
supervisorctl restart #重启所有子进程服务
supervisorctl restart name #重启子进程名字为name的服务
supervisorctl start name #开启子进程名字为name的服务
supervisorctl stop all #关闭所有子进程服务
supervisorctl stop name #停止子进程名字为name的服务
supervisorctl shutdown #关闭所有子进程服务
supervisorctl reload #重载配置文件,重启所有子进程服务
supervisorctl update #更新所有服务,一般用在添加新服务后
supervisorctl update name #更新子进程名字为name服务
启动成功后,记得去服务器开放9001端口,然后在浏览器中输入服务ip+9001 使用supervisor.conf里面配置的用户名跟密码登入使用即可。
出现界面如下,说明配置访问成功!