Python WSGI简介和uWSGI安装

Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。

uswgi学习文档
http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html

WSGI协议

首先弄清下面几个概念:
WSGI:全称是Web Server Gateway InterfaceWSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通信的规范。serverapplication的规范在PEP 3333中有具体描述。要实现WSGI协议,必须同时实现web server和web application,当前运行在WSGI协议之上的web框架有BottleFlaskDjango
uwsgi:WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet4byte为传输信息类型的描述,与WSGI协议是两种东西,据说该协议是fcgi协议的10倍快。
uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。

WSGI协议主要包括serverapplication两部分:

  • WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端;
  • WSGI application接收由server转发的request,处理请求,并将处理结果返回给serverapplication中可以包括多个栈式的中间件(middlewares),这些中间件需要同时实现server与application,因此可以在WSGI服务器与WSGI应用之间起调节作用:对服务器来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器。

WSGI协议其实是定义了一种serverapplication解耦的规范,即可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的serverapplication组合实现自己的web应用。例如uWSGIGunicorn都是实现了WSGI server协议的服务器,DjangoFlask是实现了WSGI application协议的web框架,可以根据项目实际情况搭配使用。

1.web应用的本质
1)浏览器发送一个HTTP请求
2)服务器收到请求,生成一个HTML文档
3)服务器把HTML文档作为HTTP响应的body发个浏览器
4)浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示

2.什么是WSGI,为什么需要WSGI
上面的web应用过程,如果由我们自己来实现是复杂的,接收HTTP请求,解析HTTP请求,响应HTTP请求等。
通常这些操作都由WSGI服务器来完成,WSGI(Web Server Gateway Interface)定义了WSGI服务器执行的接口,我们只需要编写服务WSGI规范的接口,然后由WSGI服务器来执行,就可以了。

3.WSGI接口编写示例

def application(environ,satrt_response):
    start_response('200 OK',[('Content-Type','text/html')])
    return '<h1>Hello,web!</h1>'

上面的application()函数就是符合WSGI标准的一个HTTP处理函数
参数说明:
environ:包含HTTP请求信息的dict对象
satrt_response:发送HTTP响应的函数
函数说明:
start_response(‘200 OK’, [(‘Content-Type’, ‘text/html’)])
发送HTTP响应的Header,Header只能发送一次,意思是start_response函数只能执行一次
‘200 OK’是HTTP响应码参数,[(‘Content-Type’, ‘text/html’)]表示HTTP Header

函数的返回值return ‘<h1>Hello,web!</h1>’作为HTTP响应body发送给服务器。

接收HTTP请求,解析HTTP请求,发送HTTP请求等操作就交由WSGI服务器去完成,WSGI接口只负责业务逻辑。

4.python WSGI服务器
python内置了一个WSGI服务器,这个模块叫做wsgiref,不过这个模块没有考虑运行效率,只是为了开发和测试使用。

5.python编写运行WSGI web应用示例
1)编写WSGI接口

def application(environ,satrt_response):
    start_response('200 OK',[('Content-Type','text/html')])
    return '<h1>Hello,web!</h1>'

2)编写server.py,启动初始化WSGI服务器,加载application()函数

# server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
from hello import application

# 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, application)
print "Serving HTTP on port 8000..."
# 开始监听HTTP请求:
httpd.serve_forever()

运行:python server.py
打开浏览器,输入http://localhost:8000/,就可以看到结果了。

部署简单的 WSGI 应用和常见的 Web 框架。

以 Ubuntu/Debian 为例,先安装依赖包:

apt-get install build-essential python-dev
Python 安装 uWSGI

1、通过 pip 命令:

pip install uwsgi

2、下载安装脚本:

curl http://uwsgi.it/install | bash -s default /tmp/uwsgi

将 uWSGI 二进制安装到 /tmp/uwsgi ,你可以修改它。

3、源代码安装:

wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gz
tar zxvf uwsgi-latest.tar.gz
cd uwsgi-latest
make

安装完成后,在当前目录下,你会获得一个 uwsgi 二进制文件。

第一个 WSGI 应用

让我们从一个简单的 “Hello World” 开始,创建文件 foobar.py,代码如下:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

uWSGI Python 加载器将会搜索的默认函数 application 。

接下来我们启动 uWSGI 来运行一个 HTTP 服务器,将程序部署在HTTP端口 9090 上:

uwsgi --http :9090 --wsgi-file foobar.py
添加并发和监控

默认情况下,uWSGI 启动一个单一的进程和一个单一的线程。

你可以用 –processes 选项添加更多的进程,或者使用 –threads 选项添加更多的线程 ,也可以两者同时使用。

uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2

以上命令将会生成 4 个进程, 每个进程有 2 个线程。
如果你要执行监控任务,可以使用 stats 子系统,监控的数据格式是 JSON:

uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

我们可以安装 uwsgitop(类似 Linux top 命令) 来查看监控数据:

pip install uwsgitop
结合 Web 服务器使用

我们可以将 uWSGI 和 Nginx Web 服务器结合使用,实现更高的并发性能。
一个常用的nginx配置如下:

location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:3031;
}

以上代码表示使用 nginx 接收的 Web 请求传递给端口为 3031 的 uWSGI 服务来处理。
现在,我们可以生成 uWSGI 来本地使用 uwsgi 协议:

uwsgi --socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

如果你的 Web 服务器使用 HTTP,那么你必须告诉 uWSGI 本地使用 http 协议 (这与会自己生成一个代理的–http不同):

uwsgi --http-socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191
部署 Django

Django 是最常使用的 Python web 框架,假设 Django 项目位于 /home/foobar/myproject:
uwsgi –socket 127.0.0.1:3031 –chdir /home/foobar/myproject/ –wsgi-file myproject/wsgi.py –master –processes 4 –threads 2 –stats 127.0.0.1:9191

–chdir 用于指定项目路径。
我们可以把以上的命令弄成一个 yourfile.ini 配置文件:

[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:9191

接下来你只需要执行以下命令即可:

uwsgi yourfile.ini
部署 Flask

Flask 是一个流行的 Python web 框架。
创建文件 myflaskapp.py ,代码如下:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "<span style='color:red'>I am app 1</span>"

执行以下命令:

uwsgi --socket 127.0.0.1:3031 --wsgi-file myflaskapp.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191

发表评论

邮箱地址不会被公开。 必填项已用*标注