(本文参考众多博客、书籍等资料,便于自己查阅和大家系统了解相关知识)
一、WSGI
在说WSGI之前,有必要介绍下Web服务的过程。当我们使用浏览器访问一个网址时,简单来说就是请求一个html文档,过程如下:
1. 浏览器向服务器发送一个HTTP请求(即HTTP请求报文),请求服务器给我这个html文档。
2. 服务器收到后,将html文档的内容封装进HTTP响应报文中,并发给浏览器。
3. 浏览器接收到HTTP响应报文后,将其中的html文档的内容取出来,并解析成我们看到的画面。
一个简单的Web服务过程就像上面所述。Apache、Nginx、Lighttpd等这些常见的静态服务器器就是干这事的。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。幸运的是,底层代码有专门的服务器器软件已经实现了,我们用Python专注于生成HTML文档即可。正因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务,这个接口就是WSGI:Web Server Gateway Interface。
WSGI是为 Python 语言定义的 Web 服务器(如uWSGI服务器)和 Web
应用程序/框架之间的一种简单而通用的接口。我们可以认为WSGI就是一个协议、一个标准。只要遵照这个协议,WSGI应用(App)就可以在任何服务器上运行。
WSGI有两方:服务器/网关一方,以及应用程序/应用框架一方。服务方调用应用方,提供环境信息,以及一个回调函数(提供给应用程序用来将消息头传递给服务器方),并接收Web内容作为返回值。
无论多么复杂的Web应用程序,入口都是一个WSGI处理理函数。 application(environ, start_response),HTTP请求的所有输入信息都可以通过environ获得,HTTP响应的输出都可以通过start_response()加上函数返回值作为Body。
所谓的 WSGI中间件,同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。“中间件”组件可以执行以下功能:
- 重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。
- 允许在一个进程中同时运行多个应用程序或应用框架。
- 负载均衡和远程处理,通过在网络上转发请求和响应消息。
- 进行内容后处理,例如应用XSLT样式表。
二、uWSGI
uWSGI是一个Web服务器,它实现了WSGI、uwsgi、http等协议。
要注意 WSGI 、uwsgi、uWSGI 这三个概念的区分。
- WSGI是一种通信协议。
- uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
- uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
特别注意:uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述。
三、nginx服务器
首先,介绍下在python+uWSGI+nginx生产环境下,浏览器访问网址的过程。
如下图所示,nginx作为反向代理服务器,接受来自浏览器的Http请求,并将Http请求发送给uWSGI,uWSGI处理请求并将关键信息传递给web应用(或django,flask等),应用返回Response经由uWSGI发送给nginx,nginx再发送给浏览器。
在上述过程中,一般静态文件都交由nginx进行传输,至于动态内容,则将其转发给uWSGI服务器进行处理,这样可以达到很好的客户端响应。特别说明:个人觉得,下图中应用程序与uWSGI之间应该是WSGI协议。不当之处请大家指点!
什么是nginx服务器?
nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强。它具有反向代理服务器的所有特点,并且配置简单,支持对大于1kb的文件进行压缩,静态文件缓存,可以大大提高访问效率。
为什么中间要加一个nginx服务器或者说nginx服务器的作用是什么?
上面介绍的uWSGI服务器也可以返回静态文件(css,js,img…),但是很笨拙。而nginx具备优秀的静态内容处理能力。而且,它还有很多其它优点,比如并发能力强、配置简单、占用内存少等之前提到的优点。
uWSGI与nginx交互
uWSGI与nginx交互,相当于两个进程间交互,一般使用的是.sock文件或者指定端口接受socket。指定端口时再使用浏览器访问相应端口,uWIGS会提示skip,跳过该HTTP请求。
nginx中,HttpUwsgiModule的作用是与uWSGI服务器进行交换。