WSGI——python web 服务器网关接口

转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html

一:服务器、服务器软件、应用程序(后台)

    我们常说“服务器”,实际上服务器是一个很宽泛的概念。

    服务器包括服务器硬件、服务器程序、以及部署在服务器上的应用程序。

    服务器硬件:也称伺服器,是提供计算服务的硬件设备,包括处理器、硬盘、内存、系统总线等。

    服务器软件:光有服务器硬件是无法提供服务的,至少需要有运行于服务器之上的操作系统、数据库软件、以及提供部署功能的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 服务器网关接口。

二:WSGI简介

    PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是一个协议,是 Python应用程序或框架 与 Web容器 之间的一种接口规范。

    只要双方都按照这个规范,分别去实现自己需要做的事,那么二者就可以顺利地进行通信。

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

三:WSGI server接口

    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接口

    WSGI application接口 接收由server转发过来的request,处理请求,并将处理结果返回给server

    接口的实现方式:

  1. 应用程序必须是一个可调用的对象
    可调用的对象有三种:
    1. 一个函数
    2. 一个类,必须实现__call__()方法
    3. 一个类的实例
  2. 这个对象接收两个参数
    从源码中,我们可以看到,这两个参数是environ, start_response. 以可调用对象为一个类为例:

    class application:
        def __call__(self, environ, start_response):
            pass
  3. 可调用对象需要返回一个可迭代的值。以可调用对象为一个类为例:

    class application:
        def __call__(self, environ, start_response):
            return [xxx]

    

五:Middleware 中间件

    middleware是介于服务器程序和应用程序中间的部分,middleware对于服务器程序(web容器)和应用程序来说都是透明的:对服务器程序来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器程序。

    因此,中间件程序需要同时实现wsgi server与wsgi application接口,可以在WSGI服务器与WSGI应用之间起调节作用。
    中间件是一个很强大的领域,相信很多同学都听说或正在担任中间件的开发工作。

    我们知道,应用程序主要是做业务逻辑实现的,那么,在请求到达应用程序之前,我们可以用来做些什么呢?一个很简单的场景,就是做请求的预处理或者基本信息提取。

    上面提到,WSGI Server调用WSGI Application时,需要两个参数:environstart_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协议其实是定义了一种serverapplication解耦的规范,即可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的serverapplication组合实现自己的web应用。例如uWSGIGunicorn都是实现了WSGI server协议的服务器,DjangoFlask是实现了WSGI application协议的web框架,可以根据项目实际情况搭配使用。
 

七:扩展:uwsgi

    uwsgi:与WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet4byte为传输信息类型的描述,与WSGI协议是两种东西,据说该协议是fcgi协议的10倍快。
 

八:扩展:uWSGI

    uWSGI旨在为部署分布式集群的网络应用开发一套完整的解决方案。主要面向web及其标准服务。由于其可扩展性,能够被无限制的扩展用来支持更多平台和语言。uWSGI是一个web服务器,实现了WSGI协议,uwsgi协议,http协议等。
uWSGI的主要特点是:

  • 超快的性能
  • 低内存占用
  • app管理
  • 详尽的日志功能(可以用来分析app的性能和瓶颈)
  • 高度可定制(内存大小限制,服务一定次数后重启等)

uWSGI服务器自己实现了基于uwsgi协议的server部分,我们只需要在uwsgi的配置文件中指定application的地址,uWSGI就能直接和应用框架中的WSGI application通信。

原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html