如何提高阅读理解理解 CGI,WSGI

拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(a743a7-ua98).
重新安装浏览器,或使用别的浏览器如何理解 CGI, WSGI? - 知乎642被浏览72601分享邀请回答251 条评论分享收藏感谢收起通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
CGI程序可以用任何脚本语言或者是完全独立编程语言实现,只要这个语言可以在这个系统上运行。
摘自维基百科
一句话总结: 一个标准,定义了客户端服务器之间如何传数据
快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。
FastCGI致力于减少网页服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的网页请求。
使用FastCGI的服务器:
Apache HTTP Server (部分)
Cherokee HTTP Server
Hiawatha Webserver
LiteSpeed Web Server
Microsoft IIS
摘自维基百科
一句话总结: CGI的升级版
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。
摘自维基百科
一句话总结: 为Python定义的web服务器和web框架之间的接口标准,如Apache和Django这种东西(虽然很少有人这么用)
一句话总结: 一个Web Server,即一个实现了WSGI的服务器,大体和Apache是一个类型的东西,处理发来的请求。
一句话总结: uWSGI自有的一个协议,
这个比较详细,也比较清楚,推荐看。
阅读(...) 评论()FROM: /blog/799163
本文不涉及WSGI的具体协议的介绍,也不会有协议完整的实现,甚至描述中还会掺杂着本人自己对于WSGI的见解。所有的WSGI官方定义请看。
WSGI是什么?
WSGI的官方定义是,the Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。
也就是说,WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理。
下面对本文出现的一些名词做定义。 wsgi app ,又称 应用 ,就是一个WSGI application。
wsgi container ,又称 容器 ,虽然这个部分常常被称为handler,不过我个人认为handler容易和app混淆,所以我称之为容器。
wsgi_middleware ,又称 中间件 。一种特殊类型的程序,专门负责在容器和应用之间干坏事的。
一图胜千言,直接来一个我自己理解的WSGI架构图吧。
可以看出,服务器,容器和应用之间存在着十分纠结的关系。下面就要把这些纠结的关系理清楚。
WSGI应用其实就是一个callable的对象。举一个最简单的例子,假设存在如下的一个应用:
Python代码 &
def&application(environ,&start_response):&&&&status&=&'200&OK'&&&&output&=&'World!'&&&&response_headers&=&[('Content-type',&'text/plain'),&&&&&&&&&&&&&&&&&&&&&&&&('Content-Length',&str(12)]&&&&write&=&start_response(status,&response_headers)&&&&write('Hello&')&&&&return&[output]&&
这个WSGI应用简单的可以用简陋来形容,但是他的确是一个功能完整的WSGI应用。只不过给人留下了太多的疑点,environ是什么?start_response是什么?为什么可以同时用write和return来返回内容?
对于这些疑问,不妨自己猜测一下他的作用。联想到CGI,那么environ可能就是一系列的环境变量,用来表示HTTP请求的信息,比如说method之类的。start_response,可能是接受HTTP response头信息,然后返回一个write函数,这个write函数可以把HTTP response的body返回给客户端。return自然是将HTTP response的body信息返回。不过这里的write和函数返回有什么区别?会不会是其实外围默认调用write对应用返回值进行处理?而且为什么应用的返回值是一个列表呢?说明肯定存在一个对应用执行结果的迭代输出过程。难道说他隐含的支持iterator或者generator吗?
等等,应用执行结果?一个应用既然是一个函数,说明肯定有一个对象去执行它,并且可以猜到,这个对象把environ和start_response传给应用,将应用的返回结果输出给客户端。那么这个对象是什么呢?自然就是WSGI容器了。
先说说WSGI容器的来源,其实这是我自己编造出来的一个概念。来源就是JavaServlet容器。我个人理解两者有相似的地方,就顺手拿过来用了。
WSGI容器的作用,就是构建一个让WSGI应用成功执行的环境。成功执行,意味着需要传入正确的参数,以及正确处理返回的结果,还得把结果返回给客户端。
所以,WSGI容器的工作流程大致就是,用webserver规定的通信方式,能从webserver获得正确的request信息,封装好,传给WSGI应用执行,正确的返回response。
一般来说,WSGI容器必须依附于现有的webserver的技术才能实现,比如说CGI,FastCGI,或者是embed的模式。
下面利用CGI的方式编写一个最简单的WSGI容器。关于WSGI容器的协议官方文档并没有具体的说如何实现,只是介绍了一些需要约束的东西。具体内容看PEP3333中的协议。
Python代码 &
&&&&&&import&cgi&&import&cgitb&&import&sys&&import&os&&&&&&environ&=&{}&&environ['REQUEST_METHOD']&=&os.environ['REQUEST_METHOD']&&environ['SCRIPT_NAME']&=&os.environ['SCRIPT_NAME']&&environ['PATH_INFO']&=&os.environ['PATH_INFO']&&environ['QUERY_STRING']&=&os.environ['QUERY_STRING']&&environ['CONTENT_TYPE']&=&os.environ['CONTENT_TYPE']&&environ['CONTENT_LENGTH']&=&os.environ['CONTENT_LENGTH']&&environ['SERVER_NAME']&=&os.environ['SERVER_NAME']&&environ['SERVER_PORT']&=&os.environ['SERVER_PORT']&&environ['SERVER_PROTOCOL']&=&os.environ['SERVER_PROTOCOL']&&environ['wsgi.version']&=&(1,&0)&&environ['wsgi.url_scheme']&=&'http'&&environ['wsgi.input']&&&&&&&&=&sys.stdin&&environ['wsgi.errors']&&&&&&&=&sys.stderr&&environ['wsgi.multithread']&&=&False&&environ['wsgi.multiprocess']&=&True&&environ['wsgi.run_once']&&&&&=&True&&&&&&&&&&sent_header&=&False&&res_status&=&None&&res_headers&=&None&&&&def&write(body):&&&&&&global&sent_header&&&&&&if&sent_header:&&&&&&&&&&sys.stdout.write(body)&&&&&&else:&&&&&&&&&&print&res_status&&&&&&&&&&for&k,&v&in&res_headers:&&&&&&&&&&&&&&print&k&+&':&'&+&v&&&&&&&&&&print&&&&&&&&&&&sys.stdout.write(body)&&&&&&&&&&sent_header&=&True&&&&def&start_response(status,&response_headers):&&&&&&global&res_status&&&&&&global&res_headers&&&&&&res_status&=&status&&&&&&res_headers&=&response_headers&&&&&&return&write&&&&&&&&def&application(environ,&start_response):&&&&&&status&=&'200&OK'&&&&&&output&=&'World!'&&&&&&response_headers&=&[('Content-type',&'text/plain'),&&&&&&&&&&&&&&&&&&&&&&&&&&('Content-Length',&str(12)]&&&&&&write&=&start_response(status,&response_headers)&&&&&&write('Hello&')&&&&&&return&[output]&&&&&&result&=&application(environ,&start_response)&&for&value&in&result:&&&&&&&write(value)&&
看吧。其实实现一个WSGI容器也不难。
不过我从WSGI容器的设计中可以看出WSGI的应用设计上面存在着一个重大的问题就是:为什么要提供两种方式返回数据?明明只有一个write函数,却既可以在application里面调用,又可以在容器中传输应用的返回值来调用。如果说让我来设计的话,直接把start_response给去掉了。就用application(environ)这个接口。传一个方法,然后返回值就是status, response_headers和一个字符串的列表。实际传输的方法全部隐藏了。用户只需要从environ中读取数据处理就行了。。
可喜的是,搜了一下貌似web3的标准里面应用的设计和我的想法类似。希望web3协议能早日普及。
Middleware中间件
中间件是一类特殊的程序,可以在容器和应用之间干一些坏事。。其实熟悉python的decorator的人就会发现,这和decoraotr没什么区别。
下面来实现一个route的简单middleware。
Python代码 &
class&Router(object):&&&&&&def&__init__(self):&&&&&&&&&&self.path_info&=&{}&&&&&&def&route(self,&environ,&start_response):&&&&&&&&&&application&=&self.path_info[environ['PATH_INFO']]&&&&&&&&&&return&application(environ,&start_response)&&&&&&def&__call__(self,&path):&&&&&&&&&&def&wrapper(application):&&&&&&&&&&&&&&self.path_info[path]&=&application&&&&&&&&&&return&wrapper&&
这就是一个很简单的路由功能的middleware。将上面那段wsgi容器的代码里面的应用修改成如下:
Python代码 &
router&=&Router()&&&&&&@router('/hello')&&def&hello(environ,&start_response):&&&&&&status&=&'200&OK'&&&&&&output&=&'Hello'&&&&&&response_headers&=&[('Content-type',&'text/plain'),&&&&&&&&&&&&&&&&&&&&&&&&&&('Content-Length',&str(len(output)))]&&&&&&write&=&start_response(status,&response_headers)&&&&&&return&[output]&&&@router('/world')&&def&world(environ,&start_response):&&&&&&status&=&'200&OK'&&&&&&output&=&'World!'&&&&&&response_headers&=&[('Content-type',&'text/plain'),&&&&&&&&&&&&&&&&&&&&&&&&&&('Content-Length',&str(len(output)))]&&&&&&write&=&start_response(status,&response_headers)&&&&&&return&[output]&&&&result&=&router.route(environ,&start_response)&&for&value&in&result:&&&&&&&write(value)&&
这样,容器就会自动的根据访问的地址找到对应的app执行了。
写着写着,怎么越来越像一个框架了?看来Python开发框架真是简单。。
其实从另外一个角度去考虑。如果把application当作是一个运算单元。利用middleware调控IO和运算资源,那么利用WSGI组成一个分布式的系统。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1079134次
积分:13703
积分:13703
排名:第904名
原创:102篇
转载:1344篇
评论:178条
1)OpenCV俱乐部
2) 视频/音频/图像/算法/ML
备注:加群需要回答问题,避免广告党。
如果你是博客看到后加的,请注明“博客”并回答问题,只注明”博客“不回答问题的恕不加入。答案为和群相关的任何技术名词,不能出现1)和2)中的任何字眼
阅读:5826
文章:16篇
阅读:10059
阅读:5015
文章:32篇
阅读:35748
(14)(46)(6)(9)(8)(8)(31)(20)(18)(42)(70)(118)(143)(56)(68)(107)(226)(78)(3)(9)(37)(46)(50)(19)(15)(13)(27)(12)(12)(103)(18)(18)| 时间排序
解决了吗?
解决了吗?
&p&可以啊,但是这样你要自己写代码解析http的请求,你明白了wsgi是什么你就知道了,只是方便解析http请求的一个协议,但是,应该没有人会这么做除非你很想了解底层代码的实现。&/p&
可以啊,但是这样你要自己写代码解析http的请求,你明白了wsgi是什么你就知道了,只是方便解析http请求的一个协议,但是,应该没有人会这么做除非你很想了解底层代码的实现。
来自子话题:
网站其实是接收http 请求,动态生成网面(拼接html字符串)的程序,但直接拼接字符串太麻烦了,所以人们把页面结构的字符串存成文件(模板),生成页面时在相应的地方填充数据就行了,为了更方便的生成页面,为模板加了逻辑处理语法....php诞生了,php本质上就是一种模板语言(虽然后来加了好多东西),所以只负责生成网页的部分,而接收http请求只能依赖http服务器了。而python是通用语言,写网站元始的玩法是自己接收http请求,拼接网页字符串返回(忽略cgi这种),为了方便写网站,python要有一种框架把http路径映射到函数,还要有模板引擎生成页面(php的套路),但是还有个问题是python自带的http服务性能不咋的,要是能用别的语言写http服务部分再转给python 就好了,于是wsgi 诞生了,wsgi 是python 与http 服务的桥梁,有了这个就产生了很多种wsgi sever(gunicorn,uWSGI等等,很多库或框架带有wsgi server如gevent,tornado等),基于多进程的,基于协程的...而框架只要支持wsgi 部可以选择各种wsgi server 来部署,php没有wsgi这样的东西,所以你不能直接用swoole直接部署你的ci框架。那php 和python的部署方式各有什么好处呢?php 更新不需要重启服务,执行完就退出不怕内存泻漏。python部署长驻内存,不依赖外部程序就能实现连接池,队列,缓存,定时任务,websocket 服务等
网站其实是接收http 请求,动态生成网面(拼接html字符串)的程序,但直接拼接字符串太麻烦了,所以人们把页面结构的字符串存成文件(模板),生成页面时在相应的地方填充数据就行了,为了更方便的生成页面,为模板加了逻辑处理语法....php诞生了,php本质上就…
&p&gunicorn是wsgi server,不支持tornado的異步IO模型&/p&
gunicorn是wsgi server,不支持tornado的異步IO模型
&p&问题解决了吗,同问。&/p&&p&我出现500的timeout超时问题,是在中断请求后若干时间后,再次请求就出现超时错误。&/p&&p&如果是连续请求的话,是没有问题的,响应速度也很快。&/p&
问题解决了吗,同问。我出现500的timeout超时问题,是在中断请求后若干时间后,再次请求就出现超时错误。如果是连续请求的话,是没有问题的,响应速度也很快。
来自子话题:
&p&我是原生党,在windows系统上,我觉得用IIS来跑django才是最吼滴。不过到了2017年,网上可参考的所有方法都不行了。开辟了新的方法:&a href=&///?target=http%3A//blog.csdn.net/gzlaiyonghao/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&在windows 2008 server 的IIS 7上运行 django 1.11 + python 3.6&i class=&icon-external&&&/i&&/a&&/p&&p&以后就参考我这篇吧。&/p&
我是原生党,在windows系统上,我觉得用IIS来跑django才是最吼滴。不过到了2017年,网上可参考的所有方法都不行了。开辟了新的方法:以后就参考我这篇吧。
&p&1.update_wrapper 这个函数的主要功能是负责copy原函数的一些属性,如__module__、__name__、__doc__等,如果你不加update_wrapper,那么被装饰的函数就会丢失其上面的一些属性信息。&/p&&p&functools 里还有个函数是wraps 是update_wrapper的更高层次封装,可以结合来一起看,才能加深了解&/p&&p&2.lambda 是匿名函数,使用方便可以查看手册&/p&
1.update_wrapper 这个函数的主要功能是负责copy原函数的一些属性,如__module__、__name__、__doc__等,如果你不加update_wrapper,那么被装饰的函数就会丢失其上面的一些属性信息。functools 里还有个函数是wraps 是update_wrapper的更高层次封装,可以结…
来自子话题:
在地铁,回家再去提供报错截图跟配置文件。我的阿里云,无法重启。回家也要解决这个问题了。
在地铁,回家再去提供报错截图跟配置文件。我的阿里云,无法重启。回家也要解决这个问题了。
Nginx 就是一个单纯的静态服务器吧,按理说没有cgi 的话你没有方法去调用你的python 函数,如果说是担心端口的事好像可以吧socket 设置到本地文件,nginx 是提供了相应的配置方法的
Nginx 就是一个单纯的静态服务器吧,按理说没有cgi 的话你没有方法去调用你的python 函数,如果说是担心端口的事好像可以吧socket 设置到本地文件,nginx 是提供了相应的配置方法的
gunicorn本身是“主从”模式(主进程+工作者进程):主进程只负责处理信号以管理工作者进程,工作者进程才会去处理用户的请求。&br&&br&&blockquote&-k gevent&/blockquote&是说, 工作者进程模式使用gevent, 而不是默认的Sync(阻塞模型)&br&&blockquote&-w&/blockquote&指定 工作者进程的数量,而不是默认的 1
gunicorn本身是“主从”模式(主进程+工作者进程):主进程只负责处理信号以管理工作者进程,工作者进程才会去处理用户的请求。 -k gevent是说, 工作者进程模式使用gevent, 而不是默认的Sync(阻塞模型) -w指定 工作者进程的数量,而不是默认的 1
使用nginx转发还是很方便的。曾经一个服务器同时跑了apache, tomcat, node3个服务。但是想做到不跨域,用url来做分发。这时候就用到nginx了。如果仅仅是一个提供API接口的后端的话,我觉得可以直接用uwsgi。
使用nginx转发还是很方便的。曾经一个服务器同时跑了apache, tomcat, node3个服务。但是想做到不跨域,用url来做分发。这时候就用到nginx了。如果仅仅是一个提供API接口的后端的话,我觉得可以直接用uwsgi。
&img src=&/v2-041d8ee4b386e93175a45_b.png& data-rawwidth=&1081& data-rawheight=&275& class=&origin_image zh-lightbox-thumb& width=&1081& data-original=&/v2-041d8ee4b386e93175a45_r.png&&
已有帐号?
无法登录?
社交帐号登录}

我要回帖

更多关于 如何理解全面从严治党 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信