zoukankan      html  css  js  c++  java
  • 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通信。

  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html
Copyright © 2011-2022 走看看