我们在用Flask开发服务端的时候,最终会面临着生产环境怎么部署的问题,难道和开发环境一样,启动入口文件,监听写定的端口就可以吗?当然不是,因为Flask自带的服务器很弱,主要是为了方便开发调试用的。而生产环境不会采用Flask自带的服务器的。生产环境应该使用gunicorn
或者uWSIG
。本文主要介绍的是gunicorn
搭建生产环境。
生产环境介绍
我会以自己的博客网站生产环境的搭建为例来说明。
生产环境
- 系统:阿里云Ubuntu 16.04
- Python版本:Python3.7
- 虚拟环境:virtualenv+virtualenvwrapper
所需工具和模块
- Flask:Python的服务器框架
- Gunicorn:WSGI的容器
- Supervisor:进程管理工具
- Nginx:反向代理服务器
生产环境的搭建
下面介绍的是搭建生产环境的主要步骤和配置,不包括python
、virtualenv
以及业务上相关模块的安装。这类安装网上资料很多,可自行进行查阅。
创建虚拟环境
在安装和配置好了virtualenv
和virtualenvwrapper
之后就可以创建虚拟环境了,当然virtualenvwrapper不是必须的,只是命令更加好用而已。
创建虚拟环境
mkvirtualenv env_flask
运行成功后我们就创建了一个env_flask的虚拟环境,你会看到用户的前缀变成了
(env_flask) root@qiye:~#
再试着运行一下python命令
Python 3.7.4 (default, Sep 29 2019, 10:03:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
pip install flask
在安装好程序运行所需要的包后,再运行
deactivate
就可以退出虚拟环境
常用的命令
-
mkvirtualenv env_name
创建虚拟环境 -
workon env_name
启动虚拟环境 -
workon
查看虚拟环境 -
deactivate
退出虚拟环境 -
rmvirtualenv env_name
删除虚拟环境
当然你也可以根据自己的喜好选择pipenv
来创建虚拟环境,它不仅可以创建虚拟环境,也是一个好用的包管理工具。
注意: 虚拟环境里的python和环境外的python是独立的,你可以想象在成一个独立的空间。环境里和环境外安装的包互不影响。
安装和配置Gunicorn
前面说过了Gunicorn是一个WSGI容器。主要用于提供http的请求和响应。他比开发服务器更强健、性能更高。
注意:这类容器很多,通常有Gunicorn
、uWSGI
、Gevent
、Waitress
等,主流的选择是Gunicorn和uWSGI。使用简单,容易配置,性能优秀。
在进入虚拟环境后,直接输入
pip install gunicorn
就可以安装了。那我们应该怎么使用呢?
最简单的使用方式如下所示:
gunicorn -w 4 -b 0.0.0.0:8001 test:app
-
w
是workers
的缩写,表示开启的进程数量,建议该值为CUP数量*2 + 1
,可以参考官网进行配置和设定 -
b
指的是监听地址和端口 -
test
表示的是入口文件 -
app
表示创建的app对象。
这样就能简单的开启服务了。是不是很简单,但是这样也并不方便服务的启停,监控等,所以经常会和进程管理工具supervisor一起使用,后面会讲到怎么和gunicorn搭配使用。
当然这里只是简单的配置和启动,还有许多配置项,我们也经常会用到。我们最好把配置写在一个文件里,然后在运行这个文件岂不是更好。它是一个python文件,比如为gunicorn_web.py
import multiprocessing
bind = '127.0.0.1:8000' # 监听的地址和端口。
workers = multiprocessing.cpu_count() * 2 + 1 # 开启的进程数
threads = multiprocessing.cpu_count() * 2 # 工作进程中线程的数量。只适用于gthread 进程工作方式
backlog = 2048 client处于waiting的数目
worker_class = "gevent" # worker进程的工作方式
worker_connections = 1000 # 客户端最大同时连接数。
daemon = False # 应用是否以daemon方式运行
errorlog = './log/gunicorn.log' # 错误日志路径
.
.
.
很多配置可以查看官网配置项
我个人的博客网站因为很简单,就没有单独写成配置文件。直接在supervisor
的配置文件里写上command=/root/.virtualenvs/env_flask/bin/gunicorn -w4 -b 0.0.0.0:8001 app:app
安装和配置Supervisor
Supervisor是一个client/server系统,是一款运行在类UNIX系统上的进程管理工具。可以很简单的控制进程的开关,启停,监听等操作。虽然是基于python开发,可使用范围却不局限于python服务。进程管理都可以使用supervisor。
早期的Supervisor版本还只支持Python2,现在版本4发布后已经完美的支持Python3了。
安装的方式有很多,根据不同的系统输入不同的安装命令,本文都是以Ubuntu 16.04
为例来进行说明。
直接用系统安装命令安装
apt-get install supervisor
安装成功后,会在/etc/supervisor
生成supervisord.conf
配置文件。
root@qiye:/etc/supervisor# ls
conf.d supervisord.conf
当然我们习惯性的不去修改默认的配置文件,而是专门把自己的配置文件单独写在指定的文件夹中,我部署的这个博客的配置就是放在conf.d
文件夹下的missoweb.conf
文件中。
采用pip进行安装
pip install supervisor
官网有更为详细的安装步骤。
配置文件
在安装成功后,就需要写配置文件了。前面说过这个博客的配置就是放在conf.d
文件夹下的missoweb.conf
文件中。
missoweb.conf
配置文件内容为
[program:missoweb]
command=/root/.virtualenvs/env_flask/bin/gunicorn -w4 -b 0.0.0.0:8001 app:app
directory=/data/MissoWebServer/
stdout_logfile=/logs/gunicorn.log
stderr_logfile=/logs/gunicorn.err
autostart=false ;
autorestart=false
这个配置很简单。常用配置下面会一一说明
-
[program:missoweb]
程序名称(用于启动,停止,重启等) -
command=
运行程序的命令,表示我用虚拟环境env_flask
里的gunicron
来启动这个项目,监听8001
端口。 -
directory=
指定启动入口的目录。 -
stdout_logfile
指定输出日志文件存放在哪里,保存在什么文件里。 -
stderr_logfile
指定错误日志文件存放在哪里,保存在什么文件里。 -
autostart
程序是否自动重启 -
autorestart
程序意外退出是否自动重启
还有很多配置项,比如设置日志文件大小、日志等级、环境变量、用户身份等,可以根据自己的需求参考配置文件进行配置。
常用命令
最常用的命令无非是启动,停止,重启等操作了。
supervisorctl reload ;修改完配置后,重新载入配置文件
supervisorctl update ;根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl status ; 查看当前各个应用的状态。
supervisorctl restart ;重启指定应用
supervisorctl stop ;停止指定应用
supervisorctl start ;启动指定应用
supervisorctl restart all ;重启所有应用
supervisorctl stop all ;停止所有应用
supervisorctl start all ;启动所有应用
也可以先在终端输入supervisorctl
进入supervisor的命令交互环境后再输入后面的命令。就像下面这样,随君喜好。
安装和配置Nginx
Ubuntu16.04
自带的有Nginx,版本很低。如果我们要用新版本的
就必须自己安装,各大系统的安装方式大同小异,这里主要介绍源码安装。我们先到nginx.org官网下载我们需要的版本。一般生产环境建议下载稳定版。我自己服务器下载的是nginx-1.16.1.tar.gz
- 解压到指定文件夹下
tar zxvf /usr/local/src/nginx-1.16.1.tar.gz -C /usr/local
这样在/usr/local
目录下就有个nginx-1.16.1
文件夹了。
- 安装Nginx
cd nginx-1.16.1
sudo ./configure --prefix=/usr/local/nginx
sudo make
sudo make install
- 配置Nginx
在完成了nginx
的安装后,当然是nginx的配置了。下面是我博客网站nginx的配置。
配置https
server {
listen 443 ssl default_server http2;
server_name www.immisso.com;
ssl_certificate /ssl/1_www.immisso.com_bundle.crt;
ssl_certificate_key /ssl/2_www.immisso.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
location / {
proxy_pass http://0.0.0.0:8001;
}
gzip on;
gzip_buffers 32 4k;
gzip_comp_level 6;
gzip_min_length 200;
gzip_types text/css text/xml application/javascript application/json;
gzip_vary on;
}
其中有些参数需要重点说明一下。
-
listen
监听的端口,开启ssl,开启http2。 -
server_name
域名。 -
ssl_certificate
https证书.crt
文件的位置 -
ssl_certificate_key
https证书.key
文件的位置 -
ssl_session_timeout
缓存有效期 -
ssl_ciphers
加密算法 -
ssl_protocols
加密协议 -
proxy_pass
运行的程序监听的端口。参考上面gunicorn监听的端口。
gzip开头的是配置http2的相关配置。具体可以参考React 首页加载慢的问题性能优化
将http重定向到https
server {
listen 80;
server_name www.immisso.com;
return 301 https://www.immisso.com$request_uri;
}
- Nginx常用命令
-
nginx
启动Nginx -
nginx -t
测试配置文件是否有语法错误 -
nginx -s reload
重新加载Nginx配置文件 -
nginx -s stop
强制停止Nginx -
nginx -s quit
优雅地停止Nginx服务(即处理完所有请求后再停止服务)
经过上面的几大步,就把我们生产环境需要的配置搭建好了。然后把代码上传到服务器,根据上面的步骤,就可以成功的部署了。