当我们执行下面的hello.py时,使用的flask自带的服务器,完成了web服务的启动。在生产环境中,flask自带的服务器,无法满足性能要求。
需要采用uWsgi或者Gunicorn来启动web服务,我们这里采用Gunicorn做wsgi容器,来部署flask程序。
Gunicorn(绿色独角兽)是一个Python WSGI的HTTP服务器。从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器与各种Web框架兼容,实现非常简单,轻量级的资源消耗。Gunicorn直接用命令启动,不需要编写配置文件,相对uWSGI要容易很多。
区分几个概念:
WSGI:全称是Web Server Gateway Interface(web服务器网关接口),它是一种规范,它是web服务器和web应用程序之间的接口。它的作用就像是桥梁,连接在web服务器和web应用框架之间。
uwsgi:是一种传输协议,用于定义传输信息的类型。
uWSGI:是实现了uwsgi协议WSGI的web服务器。
本次介绍的部署方式: nginx + gunicorn + flask
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello():
return '<h1>hello world</h1>'
if __name__ == '__main__':
app.run(debug=True)
web开发中,部署方式大致类似。简单来说,前端代理使用Nginx主要是为了实现分流、转发、负载均衡,以及分担服务器的压力。Nginx部署简单,内存消耗少,成本低。
Nginx既可以做正向代理,也可以做反向代理。
正向代理:请求经过代理服务器从局域网发出,然后到达互联网上的服务器。
特点:服务端并不知道真正的客户端是谁。
反向代理:请求从互联网发出,先进入代理服务器,再转发给局域网内的服务器。
特点:客户端并不知道真正的服务端是谁。
区别:正向代理的对象是客户端。反向代理的对象是服务端。
下面来写一个完整的部署示例。
安装命令如下:
pip3 install gunicorn
安装信息如下:
[root@server01 ~]# pip3 install gunicorn
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
Collecting gunicorn
Downloading https://mirrors.aliyun.com/pypi/packages/69/ca/926f7cd3a2014b16870086b2d0fdc84a9e49473c68a8dff8b57f7c156f43/gunicorn-20.0.4-py2.py3-none-any.whl (77kB)
|████████████████████████████████| 81kB 7.1MB/s
Requirement already satisfied: setuptools>=3.0 in /usr/local/python3/lib/python3.7/site-packages (from gunicorn) (39.0.1)
Installing collected packages: gunicorn
Successfully installed gunicorn-20.0.4
WARNING: You are using pip version 19.2.1, however version 19.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
[root@server01 ~]#
配置全局命令:安装完毕之后,全局环境是无法直接执行的,需要找到二进制文件软链接到/usr/bin
路径下。
# 安装之后,无法直接执行命令
[root@server01 ~]# gunicorn -h
-bash: gunicorn: command not found
搜索安装之后,gunicorn二进制可执行文件
的位置:
[root@server01 ~]# find / -name "*gunicorn*" -ls | grep python3 | grep bin
405121 4 -rwxr-xr-x 1 root root 236 Dec 12 08:31 /usr/local/python3/bin/gunicorn
[root@server01 ~]#
设置软链接如下:
[root@server01 ~]# ln -s /usr/local/python3/bin/gunicorn /usr/bin/gunicorn
[root@server01 ~]#
[root@server01 ~]# ls -ll /usr/bin/gunicorn
lrwxrwxrwx 1 root root 31 Dec 12 08:38 /usr/bin/gunicorn -> /usr/local/python3/bin/gunicorn
[root@server01 ~]#
配置软链接之后,就可以全局环境使用gunicorn了,例如查看版本如下:
[root@server01 ~]# gunicorn -v
gunicorn (version 20.0.4)
[root@server01 ~]#
首先准备好一个flask项目:启动flask项目之后,测试访问hello视图如下:
[root@server01 ~]# curl 127.0.0.1:5000/hello
<h1>hello world</h1>[root@server01 ~]#
测试项目能够正常访问之后,停止flask,下面来使用gunicorn启动。
查看命令行选项: 安装gunicorn成功后,通过命令行的方式可以查看gunicorn的使用信息。
[root@server01 ~]# gunicorn -h
usage: gunicorn [OPTIONS] [APP_MODULE]
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-c CONFIG, --config CONFIG
The Gunicorn config file. [None]
-b ADDRESS, --bind ADDRESS
The socket to bind. [['127.0.0.1:8000']]
....
[root@server01 ~]#
通常使用的参数:
-c CONFIG, --config=CONFIG
设定配置文件。
-b BIND, --bind=BIND
设定服务需要绑定的端口。建议使用HOST:PORT。
-w WORKERS, --workers=WORKERS
设置工作进程数。建议服务器每一个核心可以设置2-4个。
-k MODULE
选定异步工作方式使用的模块。
直接运行:
#直接运行,默认启动的127.0.0.1::8000
gunicorn 运行文件名称:Flask程序实例名
启动如下:
测试访问hello视图:
[root@server01 ~]# curl 127.0.0.1:8000/hello
<h1>hello world</h1>[root@server01 ~]#
可以看到正常访问,下面来看看指定端口号的启动方式,如下。
指定进程和端口号: -w: 表示进程(worker)。 -b:表示绑定ip地址和端口号(bind)。 -D: 后台运行
$ gunicorn -w 4 -b 127.0.0.1:5001 运行文件名称:Flask程序实例名
指定日志文件:
--access-logfile FILE
The Access log file to write to. [None]
--access-logformat STRING
The access log format. [%(h)s %(l)s %(u)s %(t)s
--error-logfile FILE, --log-file FILE
The Error log file to write to. [-]
指定access.log和error.log日志文件如下:
gunicorn -w 4 -b 127.0.0.1:5001 --access-logfile access.log --error-logfile error.log main:app
查看access.log日志信息:
查看error.log日志信息:
打开/usr/local/nginx/conf/nginx.conf文件
upstream flask{
server 127.0.0.1:5000;
server 127.0.0.1:5001;
}
server {
# 监听80端口
listen 80;
# 本机
server_name localhost;
# 默认请求的url
location / {
#请求转发到gunicorn服务器
proxy_pass http://flask;
#设置请求头,并将头信息传递给服务器端
proxy_set_header Host $host;
}
}
可以看到nginx转发gunicorn只需要通过端口号直接proxy_pass代理即可。