全面了解Nginx, WSGI, Flask之间的关系


Posted in Python onJanuary 09, 2018

概览

之前对 Nginx,WSGI(或者 uWSGI,uwsgi),Flask(或者 Django),这几者的关系一存存在疑惑。通过查阅了些资料,总算把它们的关系理清了。

总括来说,客户端从发送一个 HTTP 请求到 Flask 处理请求,分别经过了 web服务器层,WSGI层,web框架层,这三个层次。不同的层次其作用也不同,下面简要介绍各层的作用。

全面了解Nginx, WSGI, Flask之间的关系

web服务器,web框架与WSGI的三层关系

图1:web服务器,web框架与 WSGI 的三层关系

Web服务器层

对于传统的客户端 - 服务器架构,其请求的处理过程是,客户端向服务器发送请求,服务器接收请求并处理请求,然后给客户端返回响应。在这个过程中,服务器的作用是:

1 接收请求

2 处理请求

3 返回响应

Web服务器是一类特殊的服务器,其作用是主要是接收 HTTP 请求并返回响应。提起 web服务器大家都不会陌生,常见的 web服务器有 Nginx,Apache,IIS等。在上图1的三层结构中,web服务器是最先接收用户请求的,并将响应结果返回给用户。

Web框架层

Web框架的作用主要是方便我们开发 web应用程序,HTTP请求的动态数据就是由 web框架层来提供的。常见的 web框架有Flask,Django等,我们以 Flask 框架为例子,展示 web框架的作用:

from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello_world():
 return 'Hello World!'
if __name__ == '__main__':
 app.run(host='0.0.0.0', port=8080)

以上简单的几行代码,就创建了一个 web应用程序对象 app。app 监听机器所有 ip 的 8080 端口,接受用户的请求连接。我们知道,HTTP 协议使用 URL 来定位资源,上面的程序会将路径 /hello 的请求交由 hello_world 方法处理,hello_world 返回 ‘Hello World!' 字符串。对于 web框架的使用者来说,他们并不关心如何接收 HTTP 请求,也不关心如何将请求路由到具体方法处理并将响应结果返回给用户。Web框架的使用者在大部分情况下,只需要关心如何实现业务的逻辑即可。

WSGI层

WSGI 不是服务器,也不是用于与程序交互的API,更不是真实的代码,WSGI 只是一种接口,它只适用于 Python 语言,其全称为 Web Server Gateway Interface,定义了 web服务器和 web应用之间的接口规范。也就是说,只要 web服务器和 web应用都遵守WSGI协议,那么 web服务器和 web应用就可以随意的组合。

下面的代码展示了 web服务器是如何与 web应用组合在一起的。

def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b"Hello World"]

方法 application由 web服务器调用,参数env,start_response 由 web服务器实现并传入。其中,env是一个字典,包含了类似 HTTP_HOST,HOST_USER_AGENT,SERVER_PROTOCO 等环境变量。start_response则是一个方法,该方法接受两个参数,分别是status,response_headers。application方法的主要作用是,设置 http 响应的状态码和 Content-Type 等头部信息,并返回响应的具体结果。

上述代码就是一个完整的 WSGI 应用,当一个支持 WSGI 的 web服务器接收到客户端的请求后,便会调用这个 application 方法。WSGI 层并不需要关心env,start_response 这两个变量是如何实现的,就像在 application 里面所做的,直接使用这两个变量即可。

值得指出的是,WSGI 是一种协议,需要区分几个相近的名词:

uwsgi

同 wsgi 一样也是一种协议,uWSGI服务器正是使用了 uwsgi 协议

uWSGI

实现了 uwsgi 和 WSGI 两种协议的web服务器。注意 uWSGI 本质上也是一种 web服务器,处于上面描述的三层结构中的 web服务器层。

CGI

通用网关接口,并不限于 Python 语言,定义了 web服务器是如何向客户端提供动态的内容。例如,规定了客户端如何将参数传递给 web服务器,web服务器如何将参数传递给 web应用,web应用如何将它的输出如何发送给客户端,等等。

生产环境下的 web应用都不使用 CGI 了,CGI进程(类似 Python 解释器)针对每个请求创建,用完就抛弃,效率低下。WSGI 正是为了替代 CGI 而出现的。

说到这,我们基本理清了 WSGI 在 web服务器与 web框架之间作用:WSGI 就像一条纽带,将 web服务器与 web框架连接起来。回到本文的题目,Nginx 属于一种 web服务器,Flask属于一种 web框架,因此,WSGI 与 Nginx、Flask 的作用就不明而喻了。

最后以 Nginx,WSGI,Flask 之间的对话结束本文。

Nginx:Hey,WSGI,我刚收到了一个请求,我需要你作些准备,然后由Flask来处理这个请求。

WSGI:OK,Nginx。我会设置好环境变量,然后将这个请求传递给Flask处理。

Flask:Thanks WSGI!给我一些时间,我将会把请求的响应返回给你。

WSGI:Alright,那我等你。

Flask:Okay,我完成了,这里是请求的响应结果,请求把结果传递给Nginx。

WSGI:Good job!Nginx,这里是响应结果,已经按照要求给你传递回来了。

Nginx:Cool,我收到了,我把响应结果返回给客户端。大家合作愉快~

以上这篇全面了解Nginx, WSGI, Flask之间的关系就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python比较两个图片相似度的方法
Mar 13 Python
Python中尝试多线程编程的一个简明例子
Apr 07 Python
python中函数传参详解
Jul 03 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
Jan 15 Python
python 实现读取一个excel多个sheet表并合并的方法
Feb 12 Python
在PYQT5中QscrollArea(滚动条)的使用方法
Jun 14 Python
python在新的图片窗口显示图片(图像)的方法
Jul 11 Python
使用Python进行中文繁简转换的实现代码
Oct 18 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
pandas数据选取:df[] df.loc[] df.iloc[] df.ix[] df.at[] df.iat[]
Apr 24 Python
python框架flask入门之路由及简单实现方法
Jun 07 Python
python 如何利用argparse解析命令行参数
Sep 11 Python
Python设计模式之代理模式简单示例
Jan 09 #Python
基于python内置函数与匿名函数详解
Jan 09 #Python
Python设计模式之工厂模式简单示例
Jan 09 #Python
浅谈numpy库的常用基本操作方法
Jan 09 #Python
基于Python中单例模式的几种实现方式及优化详解
Jan 09 #Python
浅谈Python2获取中文文件名的编码问题
Jan 09 #Python
在CentOS6上安装Python2.7的解决方法
Jan 09 #Python
You might like
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
PHP使用strtotime获取上个月、下个月、本月的日期
2015/12/30 PHP
php实现文件与16进制相互转换的方法示例
2017/02/16 PHP
PHP单例模式模拟Java Bean实现方法示例
2018/12/07 PHP
laravel配置Redis多个库的实现方法
2019/04/10 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
仿服务器端脚本方式的JS模板实现方法
2007/04/27 Javascript
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
2007/11/30 Javascript
超级退弹代码
2008/07/07 Javascript
js 优化次数过多的循环 考虑到性能问题
2011/03/05 Javascript
关于jQuery中的end()使用方法
2011/07/10 Javascript
innerHTML与jquery里的html()区别介绍
2012/10/12 Javascript
JS获取后台Cookies值的小例子
2013/03/04 Javascript
jQuery封装的获取Url中的Get参数示例
2013/11/26 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
JavaScript 对象深入学习总结(经典)
2015/09/29 Javascript
AngularJS 最常用的功能汇总
2016/02/17 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
2016/08/05 Javascript
jQuery插件zTree实现删除树节点的方法示例
2017/03/08 Javascript
详解Vue的computed(计算属性)使用实例之TodoList
2017/08/07 Javascript
微信小程序 input输入及动态设置按钮的实现
2017/10/27 Javascript
vue系列之requireJs中引入vue-router的方法
2018/07/18 Javascript
vue父子组件的通信方法(实例详解)
2019/11/10 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
2020/06/04 Javascript
[56:56]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
Html5 webview元素定位工具的实现
2020/08/07 HTML / CSS
美国著名手表网站:Timepiece
2017/11/15 全球购物
SQL Server提供的3种恢复模型都是什么? 有什么区别?
2012/05/13 面试题
小学师德标兵先进事迹材料
2014/05/25 职场文书
乡镇党的群众路线对照检查材料
2014/09/24 职场文书
解除劳动合同协议书范本2014
2014/09/25 职场文书
2014年司机工作总结
2014/11/21 职场文书
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL