前言相信每个刚接触pythonweb开发的同学,在学习flask、django等框架的时候,肯定会被告知,在正式环境部署时,框架自带的webserver不应该用来启动对外服务,而应该提供专用的wsgi服务器(uwsgi、gunicorn等)来提供服务,为什么?在这个推荐的部署方案中,我们使用的wsgiserver和framework分别扮演什么角色呢?本文将尝试用通俗易懂的语言尽可能清楚地说明这一点。为什么需要wsgi?首先想一个问题,一个http请求从客户端到处理完成需要经过什么过程?服务端的处理可以分为两部分:与客户端交互(接收并解析请求,封装并发送响应)和根据请求参数进行相关处理。Python将这两部分分开,即有一个客户端交互的网关框架。flask、django等web框架专门负责请求逻辑处理的工作,称为application。分离后,再看上图,第2、4、5步负责网关框架;step3负责申请。大家都知道pythoner圈子里个个都是人才辈出,口齿伶俐,技术不过关。各种优秀的网关框架和应用框架即将涌现,那么这些框架如何“混搭”呢?“毛布?我们可以规定一个协议,或者网关框架和应用的设计需求;规定网关和应用分别需要实现哪些方法,以及如何调用这些方法;这样,当更好的网关框架出现时在市场上,我们可以零成本将我们的应用程序与新网关匹配。而这套协议就是wsgi。简单的说,它规定了网关如何与应用程序进行交互,以及wsgi是如何定义的。wsgi对服务器端有如下要求:1.提供接收客户端请求的服务。提供一个start_response函数供应用程序Call使用,start_response函数接收status和headers,用于设置响应状态和响应头信息(defstart_response(self,status,headers,exc_info=None):发送结果应用返回给客户端Server实现的伪代码classWsgiServer:def__init__(self,host,port,app):defserve_forever(self):#启动监听端口服务,接收请求defstart_response(self,status,headers):#用于被应用程序调用,设置status和headers...self.status=statusself.headers=headers...defhandle_request(self):#请求处理函数environ={#请求相关变量"wsgi.input":self.stdin#请求内容"wsgi.version":self.wsgi_version#wsgi版本信息...}iterResult=self.app(environ,self.start_response)#业务逻辑处理请求,返回数据in的可迭代对象iterResult:self.write(data)#s将数据一一缓存到Zoneself.send_data()#将结果返回给客户端进行申请motion有如下要求:必须是可调用对象,接收environ和start_response两个参数;environ是服务器当前解析的请求环境变量;返回值是一个可迭代对象应用程序的简单示例defapplication(environ,start_response):#Receiveenviron,start\_responsestart_response('200OK',[('Content-Type','text/html')])#调用start\_response设置响应状态和响应头信息return[b'
