前言
置信每个刚接触python web开发的同学,在学习flask、django这些框架的时候,必定会被告知说正式环境部署时,不应该用框架自带的web服务器启动对外提供服务,而应该搭配专门的wsgi服务器(uwsgi、gunicorn等)提供服务,为什么?在这套举荐的部署计划中,wsgi服务器和咱们应用的框架都各自扮演着什么角色?本文将尽可能用大白话通俗易懂的讲清楚。
为什么须要wsgi
首先,先思考一个问题,一个http申请从客户端发动到解决实现须要进过哪些流程?
服务端的解决能够分为两局部:
- 与客户端进行交互(接管并解析request,封装并发送response)
- 依据request参数进行相干的解决
python将这两局部离开来,即有专门解决客户端交互的gateway框架。而flask、django这些web框架,则是专门用于进行申请逻辑解决的工作,称为application。
离开后,再看上图,步骤2、4、5是由gateway框架负责;步骤3由application负责。
大家都晓得,pythoner圈里个个都是人才,谈话又好听,技术还强的不行,很快就涌现出各种各样优良的gateway框架和application框架了,那怎么能让这些框架实现“混搭”呢?
咱们能够规定一个协定,或者说是一个对gateway框架和application的设计要求;规定gateway和application别离都要须要实现什么办法,办法要怎么调用;这样,当市面上呈现一个更好的gateway框架时,咱们能够零老本的将咱们的application跟新的gateway搭配起来。
而这套协定,就是wsgi,简略说,它规定了gateway如何和application交互
wsgi具体是如何定义的
wsgi对于server端有以下要求:
1.提供一个接管客户端申请的服务
- 提供一个start_response函数,被application调用,start_response函数接管status和headers,用于设置响应状态和响应头部信息(def start_response(self, status, headers,exc_info=None):
- 将application返回的后果发送给客户端
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有以下要求:
- 必须是一个可调用对象,并且接管environ、start_response两个参数;environ为server端解析的以后申请环境变量;
- 返回值是一个可迭代对象
application的简略示例
def application(environ, start_response): # 接管environ、start\_response
start_response('200 OK', [('Content-Type', 'text/html')]) # 调用start\_response 用于设置响应状态和响应头部信息
return [b'<h1>Hello, web!</h1>'] # 返回一个可迭代对象,作为响应内容
发表回复