在 linux 中,有很多可以自动化管理进程的工具,但是,对于 Python 来说,我们更希望管理工具是 Python 编写的,然后又能够兼容各种程序的,不仅仅是 Web 应用,我们希望还能管理各种服务。那么在众多的选择中,我选择了 Supervisord。而这一章节我给大家分享一下我是如何使用 Supervisor 结合 Gunicorn、Flask 部署应用。

这里的应用我使用的是 《Flask Web 开发》中的 Flasky 程序,github 地址在这里,然后具体的运行过程我就不多讲述了,我直接给出了我的所有步骤,如果你有意愿更多得了解,可以阅读一下作者的这本书:Flask Web开发:基于Python的Web应用开发实战

环境说明

需要说明的是,本书的操作过程都在一个全新的测试 Ubuntu 环境下进行,所以使用的是各种自检目录和系统目录,如果你是在生产环境或者自己的电脑环境,请慎重操作!!!

预备

mkdir /home/www
cd /home/www
git clone https://github.com/luke0922/flasky.git
cd flasky
pip install virtualenv
virtualenv env
source env/bin/activate
pip install -r requirements/common.txt
pip install -r requirements/dev.txt
python manage.py init_db


安装 supervisord

apt-get install -y supervisor


配置 supervisord

安装完 supervisor 之后,它会默认创建目录:/etc/supervisor//etc/supervisor/conf.d/,其中 /etc/supervisor 中只有一个文件supervisord.conf,然后/etc/supervisor/conf.d/目录是空的。

supervisord.conf 文件是 supervisor 的主配置文件,用于配置 supervisor 运行的各项功能和参数,我这里直接给出我的配置,我的 supervisord 配置文件内容如下:

[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700

[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[include]
files = /etc/supervisor/conf.d/*.conf


这里对这个文件做一些解释:
unix_http_serversupervisorctl 项是对socket 文件进行配置,一个是服务端的 sock 文件放哪,而supervisorctl 是配置客户端以何种方式连接服务器。

rpcinterface:supervisor 这一项在官方文档中要求在标准模式下一定要有,这个没有细究,但是,需要提醒的是,如果你想使用 supervisorctl,那么应该加上这一项。

supervisord 这一项是配置一些选项设置的,照抄即可。

include 这个就是引入项目配置的配置项,我们会将项目的配置单独放在一个目录中,这个你应该是必须的,所以照抄就好。

配置项目

然后是项目配置文件,因为我们希望 supervisor 的主配置文件和各个应用的配置分开,所以各个应用的配置就在 /etc/supervisor/conf.d 目录下,然后我这里也直接给出我使用的 flasky 的配置,这个配置你可以在 flasky 应用中的 etc/flasky.conf 位置找到,我们需要这样配置:

vim /etc/supervisor/conf.d/flasky.conf


里面的内容写:

[program:flasky]
command = /home/www/flasky/env/bin/gunicorn -w 2 -b 0.0.0.0:8080 --max-requests 2000 --log-level debug --name %(program_name)s "app:create_app('development')"
directory = /home/www/flasky
environment=PATH="/home/www/flasky/env/bin", GEVENT_RESOLVER="ares"
user = root
numprocs=1
autostart=false
autorestart=true
redirect_stderr=true
redirect_stdout=true
stdout_logfile=/var/log/supervisor/%(program_name)s-out.log
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=2
stderr_logfile=/var/log/supervisor/%(program_name)s-err.log
stderr_logfile_maxbytes=100MB
stderr_logfile_backups=1


这里有几个重点,分别是:
- command: 其实就是我们使用 supervisor 运行这个应用时执行的命令,需要注意的是命令的位置
- directory:这个是应用程序的运行目录,相当于在程序中调用 getcwd 返回的值
- environment:就是我们的 virtualenv 的目录
- user:运行的用户
- autostart:当启动 supervisor 时是否自动启动应用,默认为 True
- logfile: 都是些输出日志的配置,照抄吧,自己修改一下目录即可

运行应用

首先先启动 supervisor,启动 supervisor 需要指定一下配置文件,不指定的话需要将配置放到默认的位置,但是我习惯都是指定的,所以应该这样启动:

supervisord -c /etc/supervisor/supervisord.conf


然后因为我们设置了默认不启动应用,所以我们可以看一下应用列表,使用命令:

# supervisorctl status
flasky                           STOPPED    Jul 04 03:52 PM


启动应用,应该使用这个命令:

# supervisorctl start flasky
flasky: started


然后再看一遍状态:

# supervisorctl status
flasky                           RUNNING    pid 1421, uptime 0:00:23


运行中修改配置

经常我们会 supervisor 已经启动之后又修改了文件配置,这个时候,我们不用重启supervisor,而是有一些重新读取配置的命令来配置,我都是这样操作的:

#.... update config
# supervisorctl reread
# supervisorctl update
# supervisorctl restart flasky


总共三条命令以此敲下,那么配置就更新了。

supervisor 的简单介绍就先说到这,以后有时间再继续填坑。

Reference