[英]How Python web frameworks, WSGI and CGI fit together
我有一个Bluehost帐户,我可以在其中运行Python脚本作为CGI。 我想这是最简单的CGI,因为要运行我必须在.htaccess
定义以下内容:
Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py
现在,每当我使用Python查找Web编程时,我都会听到很多关于WSGI以及大多数框架如何使用它的信息。 但我只是不明白它是如何组合在一起的,特别是当我的Web服务器被给出(Apache在主机的机器上运行)而不是我真正可以玩的东西(除了定义.htaccess
命令)。
WSGI ,CGI和框架是如何连接起来的? 如果我想在我的基本CGI配置上运行Web框架(比如web.py或CherryPy ),我需要知道,安装和执行什么操作? 如何安装WSGI支持?
WSGI,CGI和框架是如何连接的?
Apache侦听端口80.它获取HTTP请求。 它解析请求以找到响应方式。 Apache有很多响应选择。 一种回应方式是使用CGI来运行脚本。 另一种回应方式是简单地提供文件。
在CGI的情况下,Apache准备一个环境并通过CGI协议调用脚本。 这是标准的Unix Fork / Exec情况 - CGI子进程继承了包含socket和stdout的OS环境。 CGI子进程编写一个响应,返回给Apache; Apache将此响应发送到浏览器。
CGI是原始的,令人讨厌的。 主要是因为它为每个请求分配一个子进程,并且子进程必须退出或关闭stdout和stderr以表示响应结束。
WSGI是一个基于CGI设计模式的接口。 它不一定是CGI - 它不必为每个请求分叉子进程。 它可以是CGI,但它不一定是。
WSGI以几种重要方式增加了CGI设计模式。 它为您解析HTTP请求标头并将其添加到环境中。 它提供任何面向POST的输入作为环境中的类文件对象。 它还为您提供了一个能够制定响应的功能,从而避免了大量的格式化细节。
如果我想在我的基本CGI配置上运行Web框架(比如web.py或cherrypy),我需要知道/安装/做什么?
回想一下,分支子进程很昂贵。 有两种方法可以解决这个问题。
嵌入式 mod_wsgi
或mod_python
将Python嵌入到Apache中; 没有进程分叉。 Apache直接运行Django应用程序。
守护进程 mod_wsgi
或mod_fastcgi
允许Apache使用WSGI协议与单独的守护进程(或“长时间运行的进程”)进行交互。 您启动长期运行的Django进程,然后配置Apache的mod_fastcgi以与此进程通信。
请注意, mod_wsgi
可以在任一模式下工作:embedded或daemon。
当您阅读mod_fastcgi时,您会看到Django使用flup从mod_fastcgi提供的信息中创建一个WSGI兼容的接口。 管道就是这样的。
Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)
Django为各种接口提供了几个“django.core.handlers”。
对于mod_fastcgi,Django提供了一个manage.py runfcgi
,它集成了FLUP和处理程序。
对于mod_wsgi,有一个核心处理程序。
如何安装WSGI支持?
请遵循这些说明。
https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki
有关背景,请参阅此处
http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index
我认为弗洛里安的答案回答了关于“什么是WSGI”的问题部分,特别是如果您阅读了PEP 。
至于你在最后提出的问题:
WSGI,CGI,FastCGI等都是Web服务器运行代码的协议,并提供生成的动态内容。 将此与静态Web服务进行比较,其中纯HTML文件基本上按原样传递给客户端。
CGI,FastCGI和SCGI是语言无关的。 你可以用Perl,Python,C,bash等编写CGI脚本。 CGI根据URL定义将调用哪个可执行文件,以及如何调用它:参数和环境。 它还定义了在可执行文件完成后如何将返回值传递回Web服务器。 这些变化基本上是优化,能够处理更多请求,减少延迟等等; 基本概念是一样的。
WSGI只是Python。 标准函数签名定义为标准函数签名,而不是语言不可知协议:
def simple_app(environ, start_response):
"""Simplest possible application object"""
status = '200 OK'
response_headers = [('Content-type','text/plain')]
start_response(status, response_headers)
return ['Hello world!\n']
这是一个完整的(如果有限的)WSGI应用程序。 支持WSGI的Web服务器(例如带有mod_wsgi的Apache)可以在请求到达时调用此函数。
这是如此之大的原因是我们可以避免从HTTP GET / POST转换为CGI到Python的混乱步骤,并在出路时再次返回。 这是一种更加直接,清洁和高效的联系。
如果所有需要为请求完成的操作都是函数调用,那么在Web服务器后面运行长时间运行的框架也会更容易。 使用简单的CGI,您必须为每个单独的请求启动整个框架 。
要获得WSGI支持,您需要安装WSGI模块(如mod_wsgi ),或者使用带有WSGI的Web服务器(如CherryPy )。 如果这些都不可能,您可以使用PEP中给出的CGI-WSGI桥。
您可以通过CGI运行WSGI,例如Pep333演示 。 但是,每次有请求时,都会启动一个新的Python解释器,并且需要构建整个上下文(数据库连接等),这些都需要时间。
如果你想运行WSGI,最好的办法是你的主机安装mod_wsgi并进行适当的配置以将控制权推迟到你的应用程序。
对于任何可以说FCGI , SCGI或AJP的网络服务器, Flup是使用WSGI运行的另一种方式。 根据我的经验,只有FCGI真的有用,它可以通过mod_fastcgi在Apache中使用,或者如果你可以用mod_proxy_fcgi运行一个单独的Python守护进程。
WSGI是一个非常类似于CGI的协议,它定义了一组规则,即webserver和Python代码之间的交互方式,它被定义为Pep333 。 它使许多不同的Web服务器可以使用相同的应用程序协议来使用许多不同的框架和应用程序。 这非常有益,并且非常有用。
如果你不清楚这个领域的所有术语,让我们面对它,它是一个令人困惑的首字母缩略词,那么还有一个很好的背景阅读器,形式为官方python HOWTO,讨论CGI与FastCGI对比WSGI等等。 on: http : //docs.python.org/howto/webservers.html
它是Python的简单抽象层,类似于Java的Servlet规范。 虽然CGI实际上是低级别的,只是将内容转储到流程环境和标准输入/输出中,但上述两个规范将http请求和响应建模为语言中的结构。 然而,我的印象是,在Python中,人们尚未完全确定事实上的实现,因此您可以混合使用参考实现,以及提供其他内容以及WSGI支持的其他实用程序类型库(例如,粘贴)。 当然我可能是错的,我是Python的新手。 “Web脚本”社区从不同的方向(共享托管,CGI遗留,权限分离问题)解决问题,而不是Java人们开始使用(在专用环境中运行单个企业容器以防止静态编译和部署)码)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.