第一次在服务器上面部署Flask应用程序,踩了挺多坑,还好最终成功部署,记录一下。
uWSGI和Nginx
什么是Web服务器、Web框架、WSGI协议
- Web服务器:用于接受客户端请求,建立连接,转发响应的程序
 - Web框架:处理业务逻辑。如模板渲染、数据库查询
 - WSGI协议:一种
Server与Application解耦的规范,只要满足协议,那么就可以选择任意Server和Application组合成Web应用WSGI Server:负责从客户端接收请求,将Request转发给Application,将Application返回的Response返回给客户端WSGI Application:接收由Server转发的Request,处理并将结果返回给Server
 
而uWSGI,则是实现了WSGI Server协议的Web服务器,Flask是实现了WSGI Application协议的Web框架,也就是说它们可以直接组合成一个Web应用。
i> 为什么还需要Nginx
虽然可以直接由
uWSGI和Flask构成网站,但是如果访问量过大,客户端请求连接就要进行长时间的等待。此时就需要Nginx反向代理,实现分配客户端的请求连接和Web服务器的功能。安装Python3
先看看现在的Python版本,默认是
Python2$ python --version# Python 2.7.5
下载
Python3$ pwd# /root$ mkdir python && cd python$ wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
编译安装
$ tar -zxvf Python-3.7.0.tgz # 解压$ ls>>> Python-3.7.0 Python-3.7.0.tgz$ cd Python-3.7.0/$ ./configure --prefix=/usr/local/python3.7$ make && make install
备份
Python2$ mv /usr/bin/python /usr/bin/python2.7.5
如果你的系统为
centos,还需要修改yum的配置,因为其使用的是Python2$ vim /usr/bin/yum$ vim /usr/libexec/urlgrabber-ext-down# 将两个文件中的第1行都修改为Python2的路径后保存即可#!/usr/bin/python2.7.5
软链
Python3和pip3$ ln -sv /usr/local/python3.7/bin/python3.7 /usr/bin/python# $ ln -sv /usr/local/python3.7/bin/pip3.7 /usr/bin/pip3
验证
$ python -V>>> Python 3.7.0$ pip -V>>> pip... for python 3.7.0# 如果pip版本较旧可以更新一下$ python -m pip install --upgrade pip
Pip换源,适用于国内服务器
$ vim ~/.pip/pip.conf# 修改成下面的阿里源[global]index-url=https://mirrors.aliyun.com/pypi/simple/[install]trusted-host=mirrors.aliyun.com
安装虚拟环境
安装
VirtualEnv$ sudo pip install virtualenv
报错:
WARNING: The script virtualenv is installed in '/usr/local/python3.7/bin' which is not on PATH.- 原因:
virtualenv未添加到PATH中 - 可通过 
/usr/local/python3.7/bin/virtualenv调用virtualenv - 通过以下方法将
virtualenv添加到PATH中$ vim ~/.bashrc# 末尾添加以下一行然后保存退出export PATH=/usr/local/python3.7/bin:$PATH# 使配置生效$ source ~/.bashrc
 
- 原因:
 进入项目目录
$ cd /www/wwwroot/flask/
创建虚拟环境
venv_flask并进入$ virtualenv venv_flask$ source venv_flask/bin/activate# 退出虚拟环境# $ deactivate
安装项目所需依赖,注意此时是在虚拟环境中
(venv)$ pip install -r requirements.txt# 前面如果没有换源,可以通过以下命令临时使用国内源# (venv)$ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
配置uWSGI
先安装
(venv)$ pip install uwsgi
配置uWSGI。先在项目根目录创建
uwsgi.ini文件,配置如下[uwsgi]# uwsgi启动时所使用的地址与端口socket = 127.0.0.1:5000# 指向网站目录chdir = /www/wwwroot/flask# python 启动程序文件wsgi-file = app.py# python 程序内用以启动的 application 变量名callable = app# 处理器数processes = 4# 线程数threads = 2#状态检测地址stats = 127.0.0.1:9191
运行测试一下
# 提示 uwsgi: command not found 即未建立软连接# ln -s /usr/local/python3.7/bin/uwsgi /usr/bin/uwsgi(venv)$ uwsgi uwsgi.ini*** Starting uWSGI 2.0.18 (64bit) on [Tue Mar 3 20:13:35 2020] ***..........spawned uWSGI master process (pid: 17712)spawned uWSGI worker 1 (pid: 17713, cores: 2)spawned uWSGI worker 2 (pid: 17714, cores: 2)spawned uWSGI worker 3 (pid: 17716, cores: 2)spawned uWSGI worker 4 (pid: 17717, cores: 2)*** Stats server enabled on 127.0.0.1:9191 fd: 15 ***
此时已经正常启动 uwsgi 并将 Flask 项目载入其中了,
Ctrl+C关闭程序。但这只是命令启动形式,要使其随同服务器启动并作为后台服务运行才是运营环境的实际所需要。因此接下来我们需要安装另一个工具来引导 uwsgi 。配置Nginx
server{listen 80;server_name xxx.xxx.xxx.xxx; # IP或域名location / {include uwsgi_params;uwsgi_pass 127.0.0.1:5000;uwsgi_param UWSGI_PYHOME /www/wwwroot/flask/venv_flask/bin; # Python位置或虚拟环境uwsgi_param UWSGI_CHDIR /www/wwwroot/flask; # 项目根目录uwsgi_param UWSGI_SCRIPT app:app; # 启动项目的主程序}}
启动
后台运行
$ uwsgi --ini /www/wwwroot/flask/uwsgi.ini --daemonize /www/wwwroot/flask/log.out# 查看进程是否启动成功$ ps -ef | grep uwsgi# 如果需要停止服务,可以Kill掉对应的进程ID$ kill -9 进程id
其它
一开始部署到服务器时连接到数据库中没有表,一直报错。
### 经过排查才想起来还没建表,于是将代码改成这样然后手动运行了一下if __name__ == '__main__':db.create_all() # 建表### 然后再将建表的语句删除,并再次运行if __name__ == '__main__':app.run()
网上很多方法都是使用
Supervisor引用uWSGI作常规启动服务,但是我对Supervisor并不熟悉,于是就不折腾了。可以直接将后台运行语句添加到开机自启实现。- 参考
 
