首先理解下面三个概念:

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的冗余自写的。

最新文章

  1. spring boot 部署为jar
  2. 为Autodesk Viewer添加自定义工具条
  3. 51Nod 1256 乘法逆元 Label:exgcd
  4. Android的界面设计工具 DroidDraw
  5. 你可能不知道的 30 个 Python 语言的特点技巧
  6. Unity UI和引用的管理中心
  7. 采用Jenkins搭建持续集成环境
  8. 在Dll中创建对话框并调用
  9. 对Qt下对话服务器客户端的总结(MyTcpServer与MyTcpClient)
  10. tkinter第一章1
  11. tornado 采用 epoll 代理构建高并发网络模型
  12. spark运算结果写入hbase及优化
  13. linux 迁移项目ProtocolException
  14. python3 第二十七章 - 内置函数之str相关
  15. Newtonsoft.Json 概述
  16. HDU 6319 Problem A. Ascending Rating(单调队列)
  17. leetcode(js)算法之696计数二进制串
  18. 002-红黑树【B-树】、二叉查找树
  19. mysql 数据操作 目录
  20. MFC单文档带窗体创建

热门文章

  1. Angular js 过滤器 笔记(转自菜鸟教程)
  2. Business Component(BC)和Business Object(BO)
  3. jetbrain rider 逐渐完美了,微软要哭了么?
  4. tomcat、Apache服务器外网无法访问80和8080端口,其他端口可以访问
  5. python入门17 类和对象
  6. python自动化下载yunfile(未完成)
  7. log4net 配置完成后发现不能输出日志的解决方法
  8. 深搜(DFS),Image Perimeters
  9. RabbitMQ .NET Client 实战实验
  10. 【web前端】第一个移动端的心里体会