最近几天研究了一下运行flask应用的方式,所以就总结一下。
内容包括nginx+uwsgi部署flask应用,但是也包括一下其它的相关内容。

一、使用flask自带的web server

当我们完成一个flask应用的时候,通常会添加下面这段代码。

if __name__ == '__main__':
    app.run('127.0.0.1', 8080)

这就是以flask自带的web_server运行了我们所写的flask应用。点进去可以看到这个web_server是通过werkzeug.serving的run_simple实现的。

from werkzeug.serving import run_simple
try:
	run_simple(host, port, self, **options)

这里也能看到一个web_server的基本要素,监听的ip地址和端口(上面的host和port),以及处理请求的应用部分(上面的self,也就是app对象)。

flask自带的服务器有两种运行方式:多进程多线程。可以通过threaded和processes参数进行选择。需要注意的点是:1、多进程方式是采用fork()实现的,在windows上选择该模式会报错;2、多进程和多线程不能同时选择;

app.run('127.0.0.1', 8080,threaded=True,processes=1)

二、使用uwsgi部署flask应用

flask自带的服务器通常只是我们自己测试的时候用的,生产环境中常用的WSGI服务器是uwsgi。

通过pip3命令可以直接下载uwsgi,下载完成后通常建立软连接方便操作。

pip3 install uwsgi
ln -s /usr/local/python3/bin/uwsgi /usr/local/bin/uwsgi

uwsgi的配置文件如下:

[uwsgi]

http = 127.0.0.1:8081
# 当用uwsgi直接做服务器时使用http,如果外面还部署一层nginx,只是把uwsgi当作WSGI容器,用socket。

chdir = /practice/helloworld
# 项目的主目录

# virtualenv = 
# 虚拟环境路径,这里我没有用虚拟环境

wsgi-file = hello_world.py
# flask应用对象所在的py文件

callable = app
# flask应用对象

#plugin = python

master = True
# 启动主进程

vacuum = True
#设置退出后清理文件

listen = 100
# 等待队列的大小

processes = 4
# work进程的数量

# threads = 
# 每个进程可以有几个线程

thunder-lock = True
# 防止惊群

harakiri = 60
# 超过时间
daemonize = /practice/helloworld/uwsgi.log
pidfile = /practice/helloworld/uwsgi.pid

然后我们使用uwsgi --ini uwsgi.ini就可以启动uwsgi服务啦~

nginx 部署wss nginx 部署flask_nginx


查看uwsgi运行状态,可以看到有1个master进程和4个worker进程。uwsgi会以轮询的方式让4个worker进程轮流处理请求。

uwsgi服务停止指令为uwsgi --stop uwsgi.pid

三、uwsgi以协程的方式运行flask应用

uwsgi很好的支持了gevent,可以通过gevent来实现uwsgi以协程的方式运行flask应用。
通过命令uwsgi --gevent 100 --gevent-monkey-patch uwsgi.ini启动uwsgi。
其中100代表每个进程开启100个协程。运行状态如下。

nginx 部署wss nginx 部署flask_flask_02


以协程方式启动uwsgi的时候,配置文件中不能配置线程,需要注释掉。

四、nginx+uwsgi部署flask应用

nginx.conf文件如下

location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:8081;
    uwsgi_param UWSGI_PYTHON python3;
    uwsgi_param UWSGI_CHDIR /practice/helloworld;
    uwsgi_param UWSGI_SCRIPT hello_world:app;
    uwsgi_read_timeout 300;
    uwsgi_connect_timeout 300;
    uwsgi_send_timeout 300;

nginx命令启动nginx服务即可。

五、疑问

nginx 部署wss nginx 部署flask_nginx_03


以nginx+uwsgi+gevent部署flask应用时,重复访问的情况下,进程id和线程id不变,但是线程的name是在变化的,这应该和gevent的特性有关。

留个坑,看完gevent的代码后回来填坑。

——以上。