咱们常说“服务器”,实际上服务器是一个很宽泛的概念。html
服务器包括服务器硬件、服务器程序、以及部署在服务器上的应用程序。python
服务器硬件:也称伺服器,是提供计算服务的硬件设备,包括处理器、硬盘、内存、系统总线等。web
服务器软件:光有服务器硬件是没法提供服务的,至少须要有运行于服务器之上的操做系统、数据库软件、以及提供部署功能的web容器等程序。这些软件与服务器硬件一块儿,共同组成了咱们概念中的“服务器”。数据库
应用程序(后台程序):应用程序是运行在服务器上,处理请求并返回响应的程序,咱们平常所说的“web开发”、“后台开发”作的就是web应用程序的开发工做。通常,web应用程序须要部署于web容器中,而且与数据库产生数据交互。三者关系大概为:web容器负责实现一些通讯协议,而且监听服务器硬件的网关、端口,接收请求,并转发给web应用程序;web应用程序接收请求,提取请求相关信息与参数,调用中间件或者自身实现的业务逻辑(此过程或许会与数据库产生数据交互),并将处理结果以http响应的形式返回给web容器;web容器再将接收到的响应返回给浏览器进行显示。浏览器
在上面的过程当中,说起到了 web容器 与 应用程序 之间的请求转发和响应通讯,那么问题来了:web容器 有 Apahce、Nginx、Gunicorn等多种选择,而 应用程序 也可能选用Flask、Django等等各类框架进行开发,难道咱们须要针对不一样的容器或开发框架,都本身去实现一遍它们的通讯逻辑吗?固然不是。为了创建起web容器与应用程序之间的通讯规范,因而有了咱们所说的——WSGI,Web Server Gateway Interface,Python Web 服务器网关接口。服务器
PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是一个协议,是 Python应用程序或框架 与 Web容器 之间的一种接口规范。网络
只要双方都按照这个规范,分别去实现本身须要作的事,那么两者就能够顺利地进行通讯。app
WSGI
协议主要包括server
和application
两部分。框架
WSGI server接口
负责从客户端接收请求,将request
转发给application
,并将application
返回的response
返回给客户端。分布式
咱们经常使用的web容器,如Apahce、Nginx、Gunicorn等都实现了这个接口。
接口实现方式:
def run(application): #服务器程序调用应用程序实例 environ = {} #设定参数 def start_response(xxx): #设定参数 pass result = application(environ, start_response) #调用应用程序实例的__call__函数 def write(data): pass def data in result: #迭代访问 write(data)
服务器程序主要作了如下的事: 1. 设定应用程序所须要的参数 2. 调用应用程序 3. 迭代访问应用程序的返回结果,并传给客户端
WSGI application接口
接收由server
转发过来的request
,处理请求,并将处理结果返回给server
。
接口的实现方式:
这个对象接收两个参数
从源码中,咱们能够看到,这两个参数是environ, start_response. 以可调用对象为一个类为例:
class application: def __call__(self, environ, start_response): pass
可调用对象须要返回一个可迭代的值。以可调用对象为一个类为例:
class application: def __call__(self, environ, start_response): return [xxx]
middleware是介于服务器程序和应用程序中间的部分,middleware对于服务器程序(web容器)和应用程序来讲都是透明的:对服务器程序来讲,中间件扮演应用程序,对应用程序来讲,中间件扮演服务器程序。
所以,中间件程序须要同时实现wsgi server与wsgi application接口,能够在WSGI服务器与WSGI应用之间起调节做用。
中间件是一个很强大的领域,相信不少同窗都据说或正在担任中间件的开发工做。
咱们知道,应用程序主要是作业务逻辑实现的,那么,在请求到达应用程序以前,咱们能够用来作些什么呢?一个很简单的场景,就是作请求的预处理或者基本信息提取。
上面提到,WSGI Server调用WSGI Application时,须要两个参数:environ
和start_response,其中,
environ
是一个字典,它来自CGI,详情请看文档:The Common Gateway Interface Specification
文中“Environment variables”,列举了environ字典中包含的信息,主要有:
AUTH_TYPE
CONTENT_LENGTH #HTTP请求中Content-Length的部分 CONTENT_TYPE #HTTP请求中Content-Tpye的部分 GATEWAY_INTERFACE PATH_INFO #URL路径除了起始部分后的剩余部分,用于找到相应的应用程序对象,若是请求的路径就是根路径,这个值为空字符串 PATH_TRANSLATED QUERY_STRING #URL路径中?后面的部分 REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER REQUEST_METHOD #HTTP 请求方法,例如 "GET", "POST" SCRIPT_NAME #URL路径的起始部分对应的应用程序对象,若是应用程序对象对应服务器的根,那么这个值能够为空字符串 SERVER_NAME SERVER_PORT SERVER_PROTOCOL #客户端请求的协议(HTTP/1.1 HTTP/1.0) SERVER_SOFTWARE
以及客户端发起HTTP时所携带过来的一些关于客户端的信息:
HTTP_HOST = 客户端host
HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' HTTP_ACCEPT_ENCODING = 'gzip,deflate,sdch' HTTP_ACCEPT_LANGUAGE = 'en-US,en;q=0.8,zh;q=0.6,zh-CN;q=0.4,zh-TW;q=0.2' HTTP_CONNECTION = 'keep-alive' HTTP_USER_AGENT = 客户端代理信息(浏览器、内核版本等)
WSGI
协议实际上是定义了一种
server
与
application
解耦的规范,便可以有多个实现
WSGI server
的服务器,也能够有多个实现
WSGI application
的框架,那么就能够选择任意的
server
和
application
组合实现本身的
web
应用。例如
uWSGI
和
Gunicorn
都是实现了
WSGI server
协议的服务器,
Django
,
Flask
是实现了
WSGI application
协议的
web
框架,能够根据项目实际状况搭配使用。
WSGI
同样是一种通讯协议,是
uWSGI
服务器的独占协议,用于定义传输信息的类型(
type of information
),每个
uwsgi packet
前
4byte
为传输信息类型的描述,与WSGI协议是两种东西,听说该协议是
fcgi
协议的10倍快。
uWSGI
旨在为部署分布式集群的网络应用开发一套完整的解决方案。主要面向web
及其标准服务。因为其可扩展性,可以被无限制的扩展用来支持更多平台和语言。uWSGI
是一个web
服务器,实现了WSGI
协议,uwsgi
协议,http
协议等。uWSGI
的主要特色是:
app
管理app
的性能和瓶颈)uWSGI
服务器本身实现了基于uwsgi
协议的server
部分,咱们只须要在uwsgi
的配置文件中指定application
的地址,uWSGI
就能直接和应用框架中的WSGI application
通讯。