首先理解下面三个概念:

WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通信的规范。

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

uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。

WSGI协议主要包括server和application两部分:

其中application部分:

示例代码:

def application(environ, start_response):
status = '200 OK'
response_headers = [('Content-Type', 'text/html')]
# application内部调用start_response
start_response(status, response_headers) # 解析environ信息,业务逻辑处理后,返回对应的响应信息(下面代码只是模拟业务处理)
file_name = environ['PATH_INFO']
if file_name == "/index.py":
return index(file_name)
elif file_name == "/center.py":
return center(file_name)
else:
return 'Hello world a simple WSGI application!'

有了WSGI,我们在框架中只关心如何从environ这个dict(wgsi规定传过来一个字典)对象拿到HTTP请求信息,然后构造HTML,通过start_response()发送Header,最后返回Body。

整个application()函数本身没有涉及到任何解析HTTP的部分。 也就是说,底层代码不需要我们自己编写,我们只负责业务逻辑部分即可。

但是我们想一下,这个application()函数怎么调用?如果我们自己调用,两个参数environ和start_response我们没法提供,返回的str也没法发给浏览器。

截取server端部分代码实例如下:

          # 重点关注逻辑
# 准备一个字典,里面存放需要传递给web框架的数据
env = dict()
# ----------更新---------
env['PATH_INFO'] = file_name # 例如 index.py(模拟请求信息) # 重点关注逻辑
# 服务器调用框架中实现的application函数,并将包含请求信息的字典和获取响应头的函数传入
response_body = self.application(env, self.start_response)
​ # 合并header和body(响应客户端的请求,这个逻辑不用关注)
response_header = "HTTP/1.1 {status}\r\n".format(status=self.headers[0])
response_header += "Content-Type: text/html; charset=utf-8\r\n"
response_header += "Content-Length: %d\r\n" % len(response_body.encode("utf-8"))
for temp_head in self.headers[1]:
response_header += "{0}:{1}\r\n".format(*temp_head)

response = response_header + "\r\n"
response += response_body

client_socket.send(response.encode('utf-8'))

# 重点关注逻辑
# server端实现了start_response函数的定义
def start_response(self, status, headers):
"""这个方法,会在 web框架中被默认调用"""
response_header_default = [
("Data", time.time()),
("Server", "ItCast-python mini web server")
]

# 将状态码/相应头信息存储起来
# [字符串, [xxxxx, xxx2]]
self.headers = [status, response_header_default + headers]

这段代码,是在客户端请求动态资源时启动,即服务器需要向后端框架请求资源。代码解析已在代码中注释。

所以我们基本可以获得如下结论:

要实现WSGI协议,必须同时实现web server端和web application端

当前运行在WSGI协议之上的web框架有Torando,Flask,Django等

比较常用的WSGI协议服务器有:uWSGI,gunicorn等

1、框架需要实现WSGI协议,例如:Flask,Django等

2、environ 和 start_response 由 http server 提供并实现

3、environ 变量是包含了请求信息的字典

4、Application 内部在返回前调用 start_response

5、application()函数必须由WSGI服务器来调用

server要履行的任务:

1、接收HTTP请求

2、解析HTTP请求

3、准备 environ请求参数

4、定义 start_response 函数

5、组装响应头和相应体返回给客户端

application要履行的责任:

1、解析服务器发来的请求信息

2、根据请求信息,进行业务处理

3、返回所需要的数据

至此,您应该对WSGI有了一定的了解吧。

扩展阅读:

目前一些主要的实现了WSGI协议的服务器:

gunicorn

Gunicorn(从Ruby下面的Unicorn发展而来):依赖Nginx的代理行为,同Nginx进行功能上的分离。由于不需要直接处理用户来的请求(都被Nginx先处理),Gunicorn不需要完成相关的功能,其内部逻辑非常简单:接受从Nginx来的动态请求,处理完之后返回给Nginx,由后者返回给用户。

由于功能定位很明确,Gunicorn得以用纯Python开发:大大缩短了开发时间的同时,性能上也不会很掉链子。同时,它也可以配合Nginx的代理之外的别的Proxy模块工作,其配置也相应比较简单。

配置上的简单,大概是它流行的最大的原因。

uWSGI

因为使用C语言开发,会和底层接触的更好,配置也是比较方便,目前和gunicorn两个算是部署时的唯二之选。

以下是通常的配置文件

fcgi

不多说,用的少。

bjoern

Python WSGI界最牛逼性能的Server其中一个是bjoern,纯C,小于1000行代码,就是看不惯uWSGI的冗余自写的。

Python Web开发中,WSGI协议的作用和实现原理详解的更多相关文章

  1. Python Web开发中的WSGI协议简介

    在Python Web开发中,我们一般使用Flask.Django等web框架来开发应用程序,生产环境中将应用部署到Apache.Nginx等web服务器时,还需要uWSGI或者Gunicorn.一个 ...

  2. [Python WEB开发] 使用WSGI开发类Flask框架 (二)

    WSGI     Web服务器网关接口 WSGI主要规定了Web服务器如何与Web应用程序进行通信,以及如何将Web应用程序链接在一起来处理一个请求. wsgiref Python中的WSGI参考模块 ...

  3. 转载:Python Web开发最难懂的WSGI协议,到底包含哪些内容?

    原文:PSC推出的第二篇文章-<Python Web开发最难懂的WSGI协议,到底包含哪些内容?>-2017.9.27 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有 ...

  4. [译]如何在Web开发中使用Python

    [译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...

  5. Python Web框架本质——Python Web开发系列一

    前言:了解一件事情本质的那一瞬间总能让我获得巨大的愉悦感,希望这篇文章也能帮助到您. 目的:本文主要简单介绍Web开发中三大基本功能:Socket实现.路由系统.模板引擎渲染. 进入正题. 一. 基础 ...

  6. 2020 python web开发就业要求锦集

    郑州 Python程序员 河南三融云合信息技术有限公司 6-8k·12薪 7个工作日内反馈 郑州 1个月前 本科及以上2年以上语言不限年龄不限 微信扫码分享 收藏 Python程序员 河南三融云合信息 ...

  7. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  8. Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》

    首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...

  9. WEB开发中的字符集和编码

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

随机推荐

  1. SQL获取本周,上周,本月,上月的开始时间和结束时间

    ),),--本周 ),),--上周 ),),--本月 ),),--上月 ),),--近半年 ),)--近一年 ), ,, ),)--本周开始时间 ), ,, ),)--本周结束时间 ),,, ),)- ...

  2. Laravel 教程 - 实战 iBrand 开源电商 API 系统

    iBrand 简介 IYOYO 公司于2011年在上海创立.经过8年行业积累,IYOYO 坚信技术驱动商业革新,通过提供产品和服务助力中小企业向智能商业转型升级. 基于社交店商的核心价值,在2016年 ...

  3. DevExpress控件水印文字提示 z

    ButtonEdit.Properties.NullValuePrompt = "提示"; ButtonEdit.Properties.NullValuePromptShowFor ...

  4. 笨办法学Python(三十八)

    习题 38: 阅读代码 现在去找一些 Python 代码阅读一下.你需要自己找代码,然后从中学习一些东西.你学到的东西已经足够让你看懂一些代码了,但你可能还无法理解这些代码的功能.这节课我要教给你的是 ...

  5. css3 兼容性

    为了准确快速的知道css3对浏览器的兼容性(这里主要针对ie), 做了一个简单的表格

  6. mysql使用mysqld_multi工具启动多实例

    先给出实验环境/etc/my.cnf文件内容修改内容为:添加了[mysqld_multi]标签和多出来两个数据库的标签[mysqld3307]和[mysqld3308]配置完成后启动方法,举一例:my ...

  7. UNIX PIPES 管道原稿

    40年前,Unix操作系统横空出世,Unix不仅仅带来了一个操作系统,还创造C语言,Socket,开源,黑客等等文化,这些文化影响着整个计算机世界的文明,直到今天. 如果说Unix是计算机文明中最伟大 ...

  8. C#多线程最简单Demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. wordpress建设的企业网站

    wordpress企业站 http://ahlajd.demo.phpfangzhan.com 后台焦点图实现:

  10. 菜鸟笔记 -- Chapter 11 格式化

    我们在String中介绍过它有一个格式化的方法,在其它很多地方,也都能看到格式化的操作,那么这节我们就来认真了解一下Java中的格式化操作. 我们在操作中涉及到的格式化有字符串的格式化和一些其它数据类 ...