上一篇文章介绍了如何使用uWSGI将部署一个简单的hello world WSGI application,并介绍了uWSGI的processes,threads,status参数和一个查看uwsgi状态的小工具——uwsgitop。但是我们正常的开发过程中,不会自己从头到尾实现WSGI application,而是会使用一些框架,比如Django,Flask,Bottle等。这一章以Flask为例介绍如何使用uWSGI部署Flask app应用。
首先编写一个最简单的Flask app,命名为flaskapp.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "I am Flask app
"
然后可以测试使用Flask自带的WSGI server启动:
export FLASK_APP=flaskapp.py
flask run --host 0.0.0.0
然后可以通过浏览器访问http://localhost:5000访问到这个服务的页面。
有了第一章介绍的WSGI的基础,我们已经认清了Flask这类web框架的本质,他们都会生成一个WSGI application,然后可以使用一个WSGI server(可以是框架自带的,也可以是uWSGI这类高性能的第三方网关)将其运行部署起来。所以Flask生成的app和我们前面自己写的app在实现WSGI协议的层面上没有本质区别,可以使用前面的方法利用uWSGI将其部署起来。
uwsgi --http :9090 --wsgi-file flaskapp.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191
然后可以通过浏览器输入http://localhost:9090访问这个服务
在实际的生产环境中,一般会在应用服务前面放一个功能更为强大的web服务器,比如nginx。
uWSGI支持HTTP,FastCGI,SCGI协议,同时他又有一个自创的协议,就叫做“uwsgi”,uWSGI支持的这些个协议中,性能最好的是uwsgi,这个协议目前已经被nginx所支持。可以在nginx的配置中增加如下配置:
http {
......
server {
listen 30000;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
}
}
这段配置表示任何到达30000端口的请求都会以uwsgi协议的形式绑定到3031端口
然后,我们可以使用uwsgi协议再次启动Flask服务:
uwsgi --socket 127.0.0.1:3031 --wsgi-file flaskapp.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191 --stats-http
到这一步先暂停一下,研究一下通过--http和--socket两种方式启动uwsgi的进程
先看http的启动方式:
uwsgi --http :9090 --wsgi-file flaskapp.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191
可以看到如下log:
内容粘贴如下:
*** Starting uWSGI 2.0.18 (64bit) on [Sun Dec 8 16:49:37 2019] ***
compiled with version: 5.4.0 20160609 on 07 December 2019 03:27:13
os: Linux-4.15.0-72-generic #81~16.04.1-Ubuntu SMP Tue Nov 26 16:34:21 UTC 2019
nodename: zhr-VirtualBox
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /home/zhr/disk1/study/blog_code/uwsgi/p3_uwsgi
detected binary path: /home/zhr/disk1/study/blog_code/venv/bin/uwsgi
your processes number limit is 31670
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :9090 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:45951 (port auto-assigned) fd 3
Python version: 3.5.2 (default, Oct 8 2019, 13:06:37) [GCC 5.4.0 20160609]
Python main interpreter initialized at 0x272c530
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 416880 bytes (407 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x272c530 pid: 24477 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 24477)
spawned uWSGI worker 1 (pid: 24479, cores: 2)
spawned uWSGI worker 2 (pid: 24480, cores: 2)
spawned uWSGI worker 3 (pid: 24481, cores: 2)
spawned uWSGI worker 4 (pid: 24482, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 18 ***
spawned uWSGI http 1 (pid: 24483)
,我们观察到uWSGI启动了6个进程,一个是pid为24477的master进程,还有四个pid分别为24479,24480,24481,24482的四个worker进程,还有一个pid为24483的http进程,从ps也能看出,一共是六个进程:
然后再来看--socket的启动方式:
uwsgi --socket 127.0.0.1:3031 --wsgi-file flaskapp.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191
可以看到如下log信息:
内容粘贴如下:
*** Starting uWSGI 2.0.18 (64bit) on [Sun Dec 8 17:03:32 2019] ***
compiled with version: 5.4.0 20160609 on 07 December 2019 03:27:13
os: Linux-4.15.0-72-generic #81~16.04.1-Ubuntu SMP Tue Nov 26 16:34:21 UTC 2019
nodename: zhr-VirtualBox
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /home/zhr/disk1/study/blog_code/uwsgi/p3_uwsgi
detected binary path: /home/zhr/disk1/study/blog_code/venv/bin/uwsgi
your processes number limit is 31670
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:3031 fd 3
Python version: 3.5.2 (default, Oct 8 2019, 13:06:37) [GCC 5.4.0 20160609]
Python main interpreter initialized at 0x259d450
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 416880 bytes (407 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x259d450 pid: 25069 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 25069)
spawned uWSGI worker 1 (pid: 25071, cores: 2)
spawned uWSGI worker 2 (pid: 25072, cores: 2)
spawned uWSGI worker 3 (pid: 25073, cores: 2)
spawned uWSGI worker 4 (pid: 25074, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 15 ***
可以看到,http的进程不见了,只有五个今进程,通过ps也可以证实这一点:
目前看来,启动命令有点长,可以将它们放到配置文件里面。创建文件flaskapp.ini
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/zhr/disk1/study/blog_code/uwsgi/p3_uwsgi/
wsgi-file = flaskapp.py
processes = 4
threads = 2
stats = 127.0.0.1:9191
然后可以通过命令 uwsgi --ini flaskapp.ini来启动