相信每一个刚接触python web开发的同窗,在学习flask、django这些框架的时候,确定会被告知说正式环境部署时,不该该用框架自带的web服务器启动对外提供服务,而应该搭配专门的wsgi服务器(uwsgi、gunicorn等)提供服务,为何?在这套推荐的部署方案中,wsgi服务器和我们使用的框架都各自扮演着什么角色?本文将尽量用大白话通俗易懂的讲清楚。html
首先,先思考一个问题,一个http请求从客户端发起处处理完成须要进过哪些流程?
服务端的处理能够分为两部分:python
python将这两部分分开来,即有专门处理客户端交互的gateway框架。而flask、django这些web框架,则是专门用于进行请求逻辑处理的工做,称为application。web
分开后,再看上图,步骤二、四、5是由gateway框架负责;步骤3由application负责。django
你们都知道,pythoner圈里个个都是人才,说话又好听,技术还强的不行,很快就涌现出各类各样优秀的gateway框架和application框架了,那怎么能让这些框架实现“混搭”呢?
咱们能够规定一个协议,或者说是一个对gateway框架和application的设计要求;规定gateway和application分别都要须要实现什么方法,方法要怎么调用;这样,当市面上出现一个更好的gateway框架时,咱们能够零成本的将咱们的application跟新的gateway搭配起来。flask
而这套协议,就是wsgi,简单说,它规定了gateway如何和application交互缓存
1.提供一个接收客户端请求的服务服务器
Server端实现伪码并发
class WsgiServer: def __init__(self, host, port, app): def serve_forever(self): # 启动监听端口服务,接收请求 def start_response(self, status, headers): # 用于被application调用,设置status和headers ... self.status = status self.headers = headers ... def handle_request(self): # 请求处理函数 environ = { # 请求相关变量 "wsgi.input": self.stdin # request内容 "wsgi.version": self.wsgi_version # wsgi版本信息 ... } iterResult = self.app(environ, self.start_response) # 业务逻辑处理请求,返回可迭代对象 for data in iterResult: self.write(data) # 将数据挨个发送到缓存区 self.send_data() # 将结果返回给客户端
application的简单示例app
def application(environ, start_response): # 接收environ、start\_response start_response('200 OK', [('Content-Type', 'text/html')]) # 调用start\_response 用于设置响应状态和响应头部信息 return [b'<h1>Hello, web!</h1>'] # 返回一个可迭代对象,做为响应内容