Flask 是一个使用 Python 编写的轻量级Web 应用框架。Flask的目的是要建立一个非常稳定和可靠的Web应用的基础系统,我们可以使用Flack再加上各种插件,扩展和其他模块,能够构建功能强大的网站和应用。根据2019年的使用情况数据可看出,主流 Python Web 框架包括:django、Flask、Tornado、Web2Py 等,web.py由于其原作者的仙逝,近些年表现出颓疲的状态,令人惋惜不已。
本教程在云服务器上安装了WSGI (Web Server Gateway Interface )接口 及 Http Sever (如 Apache、Nginx等)。
Python Web环境 -> Flask+ Nginx + Gunicorn + Supervisor
Flask是Web框架、Nginx 提供对外的服务、Gunicorn为WSGI服务器、Supervisor来守护进程。
注:本教程在Python3.x版本运行,安装可参考:Python3.x的安装及相关设置
此前基于云服务器部署Python Web环境(Nginx+Spawn-fcgi+web.py)的教程可以按需参阅。
安装VirtualEnv
Ubuntu下安装VirtualEnv:
1
sudo pip install virtualenv
创建venv文件夹,并安装虚拟环境:
1
2
3
4
5
6
7
8创建文件夹,或者进入自己的项目文件夹
mkdir project
进入该文件夹
cd project
安装虚拟环境
virtualenv venv
会提示如下的信息
> created virtual environment CPython3.7.5.final.0-64 in 546ms ...
激活虚拟环境:
1
2
3激活虚拟环境
source venv/bin/activate
退出虚拟环境:deactivate启用虚拟环境后,命令行状态进入虚拟环境的状态,如下:
1
(venv) ~/project#
安装Flask
通用安装方法:
在激活的虚拟环境中安装Flask
1
2在激活的虚拟环境中安装Flask
(venv) ~/project$ pip install Flask测试
Flask
,新建hello.py
内容如下:hello.py 1
2
3
4
5
6
7
8
9
10
11
12
13#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
def hello():
return 'Hello World!'
if __name__ == "__main__":
app.run() # 启动应用运行该代码:
1
2python hello.py
提示:* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
另开一个终端,输入curl 127.0.0.1:5000
,其中端口号与上方一致,显示结果为:
Hello, World!
修改Flask的默认端口:
1 | env FLASK_APP=hello.py flask run -p 5001 |
安装Nginx
Ubuntu下可使用下述命令:
1
sudo apt-get install nginx
安装好的文件位置:
/usr/sbin/nginx:主程序
/etc/nginx:存放配置文件
/usr/share/nginx:存放静态文件
/var/log/nginx:存放日志
其实从上面的根目录文件夹可以知道,Linux系统的配置文件一般放在/etc,日志一般放在/var/log,运行的程序一般放在/usr/sbin或者/usr/bin。
如果要更清楚Nginx的具体配置项,可以打开/etc/nginx/nginx.conf
对于其他Linux系统可参照官网链接:https://www.nginx.com/resources/wiki/start/topics/tutorials/install/
启动Nginx:
1
2启动Nginx
sudo /etc/init.d/nginx start其他相关命令:
1
2
3
4关闭Nginx
sudo /etc/init.d/nginx stop
重启Nginx
sudo /etc/init.d/nginx restart访问
xx.xx.xx.xx
(其中xx.xx.xx.xx
更换为云服务器的公网IP),显示结果为:Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.Thank you for using nginx.
安装Gunicorn
安装Gunicorn
1
pip install gunicorn
配置 nginx.conf 支持 Gunicorn
1
2编辑配置文件
vim /etc/nginx/nginx.conf在
http
内如下之处:1
2
3
4http
{
server{}
}添加以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19server{
listen 80;
server_name xx.xx.xx.xx; # 其中xx.xx.xx.xx更换为云服务器的公网IP
index index.html index.php;
location /hello {
proxy_pass http://127.0.0.1:9001; # 把请求通过gunicorn传送给本机的9001端口
proxy_redirect off;
proxy_set_header Host $host:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ { # 配置静态文件的访问
if (-f $request_filename) { # 如果请求文件名是一个文件
rewrite ^/static/(.*)$ /static/$1 break; # 直接跳转到对应的资源,中断fastcgi的传输
}
}
}
特别注意:【此处尤为重要,一开始始终无法正常显示,我花费了一下午的时间才解决相关问题】
- 在云服务器【安全组】的
入站规则
和出站规则
分别添加80、90、50
端口; - 重启Nginx:
sudo /etc/init.d/nginx restart
; nginx.conf
中proxy_pass http://127.0.0.1:5000
端口号可以更改,但是需要保持与启动Gunicorn进程中的相同,同事注意修改端口号后要重启Nginx。
启动应用
启动一个Gunicorn进程:
1
2启动进程
gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
-D: 后台运行
-w: 代表启动5个进程(worker),可以通过ps -ef | grep 9001 可以看到四个PID;-b: 打标绑定的IP和端口号,0.0.0.1表示不仅仅能在本台机器上访问,外网也可以访问,绑定的为9001端口
main:app**, wsgi代表文件名,app为对应到该文件中创建的Flask对象
此外还有其他参数:-log-level LEVEL:表示日志级别,测试可以用DEBUG
-timeout: 超时时间,单位是秒
—access-logfile access.log:访问日志
—error-logfile error.log:错误日志
注:可以随意填写地址和端口信息,但是一定需要和Nginx配置文件相匹配。
启动Nginx
1
2启动Nginx
sudo /etc/init.d/nginx start查看9001端口是否存在
1
netstat -ano |grep 9001
若存在则显示:
tcp 0 0 127.0.0.1:9001 0.0.0.0:* LISTEN off (0.00/0/0)
访问
xx.xx.xx.xx/hello
(其中xx.xx.xx.xx
云服务器的公网IP),显示结果为:Hello, world!
关闭/重启应用
查看Gunicorn进程树:
1
pstree -ap|grep gunicorn
显示如下:
1
2
3
4
5
6
7
8
9
10
11
12
13|-gunicorn,24610 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
| |-gunicorn,24613 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
| |-gunicorn,24614 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
| |-gunicorn,24615 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
| |-gunicorn,24616 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
| `-gunicorn,24622 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:9001 hello:app
|-gunicorn,25266 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| |-gunicorn,25269 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| |-gunicorn,25270 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| |-gunicorn,25271 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| |-gunicorn,25272 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| `-gunicorn,25273 /root/cong/venv/bin/gunicorn -D -w 5 -b 127.0.0.1:5000 hello:app
| | |-grep,26544 --color=auto gunicorn退出一个Gunicorn进程:
1
2如退出上方的24610进程
kill -9 24610重启进程:
1
2如重启上方的25266进程
kill -HUP 25266
安装 Supervisor
Supervisor是一个使用Python开发的进程管理程序
安装supervisor:
1
pip install supervisor
生成配置文件
1
2
3
4
5
6创建 /etc/supervisor 文件夹
mkdir /etc/supervisor
生成 supervisord.conf 文件
echo_supervisord_conf > /etc/supervisor/supervisord.conf
为supervisord.conf增加执行权限
chmod +x /etc/supervisor/supervisord.conf修改
supervisord.conf
最后的[include]
部分配置:1
2[include]
files = /etc/supervisor/conf.d/*.conf这样就可以支持子配置文件,而不用改动主配置文件。
在
/etc/supervisor/conf.d/
新增子进程配置文件hello.conf
:1
2
3
4
5
6
7创建 /etc/supervisor/conf.d 文件夹
cd /etc/supervisor
mkdir conf.d
创建hello.conf 文件
cd /etc/supervisor/conf.d
为hello.conf增加执行权限
chomod +x hello.conf创建
hello.conf
配置文件如下:1
2
3
4
5
6
7
8[program:hello]
command=/root/cong/venv/bin/gunicorn -w 5 -b 127.0.0.1:9001 hello:app
directory=/root/cong //项目目录
user=root
autorestart=true //设置自动重启
startretires=3 //重启失败3次
[supervisord]在上面的配置文件中,
[program:hello]
设置了进程名,这与之后操作进程的状态名称有关,为hello
;command
为进程运行的命令,必须使用绝对路径,并且使用虚拟环境下的gunicorn
命令;user
指定了运行进程的用户,这里设置为root
注意hello.conf中不要有汉字
启动这个
demo
进程:1
supervisord -c /etc/supervisor/conf.d/hello.conf
停止进程
1
2
3
4找到supervisord进程编号
ps -ef | grep supervisord
kiil进程
kiil -9 24918因为在虚拟环境中安装了Supervisor,我的supervisorctl无法使用,在虚拟环境之外也另外安装了Supervisor,解决了部分问题。总之Supervisor对Python3.x支持效果不好。
导出pip安装包记录
将虚拟环境中安装的包记录到requirements.txt中:
1 | pip freeze > requirements.txt |
当该项目被迁移到其他机器时,直接运行(或新建一个虚拟环境,再运行该命令):
1 | 安装所需要的包 |
Debug
Bug 1: 出现
1 | The 'supervisor==3.3.1' distribution was not found and is required by the application |
解决方法:
通过apt-get
安装的supervisor,实际上是按照Python2.x版本中。但由于我把ubuntu的python默认环境改成3.7,在Python3使用supervisor其实是借用Python2的环境,所以通过apt-get
安装的supervisor显然不可行。
直接用Python3.x版本通过pip安装,会提示:
1 | Supervisor requires Python 2.4 or later but does not work on any version of Python 3. You are using version 3.7.5 (default, Nov 7 2019, 10:50:52) |
安装上文中通过pip进行安装,应该不会出现此问题。
Bug 2: 出现
1 | Error: .ini file does not include supervisord section |
意思是少了 [supervisrod] 配置项,严格按照上方的流程不会出现此问题,可以参考 [supervisord-section-settings增添其他配置选项。