万恶的uwsgi,uWSGI,WSGI命名

前言

我们在用python做web开发时候经常会听到这几个词,uwsgi,uWSGI,WSGI,不知道这些是哪个怪人起的名字,没啥区分度?接下来我给大家撸一撸他们的关系以及每个名词的含意

这些怪东西想解决的问题

为了解决web服务器和应用服务器的完全分离,于是有了WSGI规范,这里的应用服务器就是我们的python代码,我们写的python代码只需要遵循WSGI规范就可以让uWSGI服务器通过uwsgi协议直接调用,如下图所示。

201706052476420160416100740_83119.png

WSGI

WSGI的全称是Web Server Gateway Interface,这是一个规范,描述了web server如何与web application交互、web application如何处理请求。该规范的具体描述在PEP 3333。注意,WSGI既要实现web server,也要实现web application

实现了WSGI的模块/库有wsgiref(python内置)、werkzeug.serving、twisted.web等,具体可见Servers which support WSGI

当前运行在WSGI之上的web框架有Bottle、Flask、Django等,具体可见Frameworks that run on WSGI

WSGI server所做的工作仅仅是将从客户端收到的请求传递给WSGI application,然后将WSGI application的返回值作为响应传给客户端。WSGI applications 可以是栈式的,这个栈的中间部分叫做中间件,两端是必须要实现的application和server。

WSGI application

WSGI application结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def application (environ, start_response):

response_body = 'Request method: %s' % environ['REQUEST_METHOD']

# HTTP响应状态
status = '200 OK'

# HTTP响应头,注意格式
response_headers = [
('Content-Type', 'text/plain'),
('Content-Length', str(len(response_body)))
]

# 将响应状态和响应头交给WSGI server
start_response(status, response_headers)

# 返回响应正文
return [response_body]

这是一段遵循WSGI标准的python代码,函数application里面有两个参数,一个是环境变量,一个是回调函数,环境变量是web服务器解析了http请求报文,然后告诉应用服务器一些http信息,写进环境变量,回调函数是为了让应用服务器把处理结果返回给web服务器

WSGI Server

WSGI server就是一个web server,他做的最主要工作是接收request信息并解析为http协议信息,然后传递给应用服务器来处理,以及返回给客户端response信息,其处理一个HTTP请求的逻辑如下:

1
2
3
iterable = app(environ, start_response)
for data in iterable:
# send data to client

app即WSGI application,environ即上文中的environment。可调用对象app返回一个可迭代的值,WSGI server获得这个值后将数据发送给客户端。

uwsgi

uwsgi是uWSGI的私有协议,据说该协议大约是fcgi协议的10倍那么快。

uWSGI

uWSGI是我们重点介绍的部分,主要分三块

1.uWSGI功能说明 2.uWSGI实战演练 3.uWSGI monitor介绍

uWSGI功能说明

uWSGI是一个web服务器,原生支持HTTP, FastCGI, SCGI协议,并有自己的私有协议 uwsgi (令人抓狂的命名),支持nginx 和 Cherokee 配套使用,在mac环境下我们可以通过 pip install uwsgi 来对uWSGI进行安装

1
2
3
4
5
6
uWSGI的主要特点如下:
超快的性能
低内存占用(实测为apache2的mod_wsgi的一半左右)
多app管理
详尽的日志功能(可以用来分析app性能和瓶颈)
高度可定制(内存大小限制,服务一定次数后重启等)

uWSGI实战演练

下面告诉大家如何用uWSGI模块将我们的python代码启动起来,供浏览器访问

foobar.py

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

这里是一段符合WSGI规范的应用服务器的代码,我们打算将它用uWSGI跑起来,uwsgi --http :9090 --wsgi-file foobar.py,通过web浏览器我们就可以通过9090端口来对应用服务器进行访问了

uwsgi功能非常强大,还支持多实例,多线程,类似nginx的配置方式

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

这里代表用http协议,起四个进程,每个进程双线程,实际启动后,我们可以根据 ps 命令在后台对程序进行查看

uWSGI monitor介绍

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

uWSGI提供了monitor功能,能够对uWSGI服务器进行性能监控,如这里monitor启用的就是9191端口,等待客户端连接

我们可以使用 uwsgi --socket 127.0.0.1:9191 --nagios 去获取monitor数据,但他的缺点是每次只能获取一次,当然我们还有更好的办法去获取monitor数据,可以试试 uwsgitop,可以展现出类似 Linux的 top 命令的显示效果

uwsgitop localhost:9191

参考资料

https://shenwang.blog.ustc.edu.cn/nginx%E5%92%8Cuwsgi%E9%80%9A%E4%BF%A1%E6%9C%BA%E5%88%B6/ http://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html http://xiaorui.cc/2016/04/16/%E6%89%93%E9%80%A0mvc%E6%A1%86%E6%9E%B6%E4%B9%8Bwsgi%E5%8D%8F%E8%AE%AE%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9%E5%8F%8A%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0/ http://www.letiantian.me/2015-09-10-understand-python-wsgi/ https://github.com/xrmx/uwsgitop

坚持原创技术分享,您的支持将鼓励我继续创作!