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通信。

  • 相关阅读:
    技术实践 | 聊聊网易云信的信令网络库实践
    打破传统降噪技术 看网易云信在语音降噪的实践应用
    聊聊前端日志库在 SaaS 产品中的应用与设计
    WebRTC 系列之音频会话管理
    简单五步,轻松构建本土「Clubhouse」
    网易云信服务监控平台实践
    基于 Elasticsearch 的数据报表方案
    基于 WebRTC 实现自定义编码分辨率发送
    Python 设计模式—原型模式
    网络层—简单的面试问题
  • 原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html
Copyright © 2011-2022 走看看