Python Web框架,WSGI和CGI如何结合在一起


150

我有一个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.pyCherryPy),该怎么办?如何安装WSGI支持?

Answers:


242

WSGI,CGI和框架如何连接?

Apache侦听端口80。它获取HTTP请求。它解析请求以找到一种响应方式。Apache有很多可供选择的响应方式。一种响应方式是使用CGI运行脚本。另一种响应方式是简单地提供文件。

对于CGI,Apache准备一个环境并通过CGI协议调用脚本。这是标准的Unix Fork / Exec情况-CGI子进程继承了包括套接字和标准输出的OS环境。CGI子进程编写一个响应,该响应可以返回到Apache。Apache将此响应发送到浏览器。

CGI是原始且令人讨厌的。主要是因为它为每个请求派生一个子流程,并且该子流程必须退出或关闭stdout和stderr来表示响应结束。

WSGI是基于CGI设计模式的接口。它不一定是CGI,也不必为每个请求派生一个子进程。可以是CGI,但不一定如此。

WSGI以几种重要方式添加到CGI设计模式中。它为您解析HTTP请求标头,并将其添加到环境中。它提供任何面向POST的输入,作为环境中的类似文件的对象。它还为您提供了可以制定响应的功能,从而使您免于许多格式设置细节。

如果要在基本CGI配置上运行Web框架(例如web.py或cherrypy),我需要知道/安装/做什么?

回想一下,分叉子过程很昂贵。有两种方法可以解决此问题。

  1. 在Apache中嵌入mod_wsgimod_python嵌入Python;没有分叉的过程。Apache直接运行Django应用程序。

  2. 守护程序, mod_wsgimod_fastcgi允许Apache使用WSGI协议与单独的守护程序(或“长时间运行的进程”)进行交互。您启动长期运行的Django进程,然后配置Apache的mod_fastcgi与该进程进行通信。

请注意,它mod_wsgi可以在两种模式下工作:嵌入式或守护程序。

当您阅读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


4
我无法安装mod_wsgi,因为我位于共享主机上。我只有fcgi支持。我如何仍可以通过它运行WSGI应用程序?
Eli Bendersky

3
+1就是一个很好的答案,可以回答我想到的很多(但不是全部)问题。这个答案仍然不完整。您对CGI和WSGI的解释很好,但是FASTCGI和WSGI之间的关系和区别是什么?哪个更好?它们如何运作?mod_python是如何进入画面的?

14
S.Lott没有抱怨什么时候人们问哪个“更好”,为什么不简单地说“ mod_wsgi比X更好,fastcgi比Y更好”,并且如果OP有更具体的问题,他们会问。
Gregg Lind

7
@Greg Lind:为什么不简单地说“ mod_wsgi比X好,fastcgi比Y好”?因为这不是很容易做到。X和Y集的元素有数十种非功能性品质因数。很难一一列举。人们对有关的质量因素提出具体问题要好得多。
S.Lott

4
仅作说明:自1.7版以来,不推荐使用runfcgi选项,并且在Django 1.9中删除了FastCGI支持。
OBu

58

我认为Florian的答案回答了您有关“ WSGI是什么”的部分问题,特别是如果您阅读了PEP

至于您即将提出的问题:

WSGI,CGI,FastCGI等都是Web服务器运行代码并传递产生的动态内容的协议。与此相比,静态Web服务基本上是将纯HTML文件原样发送到客户端的静态Web服务。

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桥。


3
不让WSGI语言不可知的是谁的愚蠢想法?那有什么意义呢?也可以将整个Python作为Apache模块发布。
Salman von Abbas

2
@SalmanPK我认为这只是一个权衡。当然,要想简单地以所选语言实现功能就可以使用与语言无关的协议(如果不是不可能的话)。
phunehehe 2013年

21

如Pep333所示,您可以在CGI上运行WSGI。但是,每次有一个请求时,都会启动一个新的Python解释器,并且需要构建整个上下文(数据库连接等),这都需要时间。

如果要运行WSGI,最好的方法是主机安装mod_wsgi并进行适当的配置以将控制权交给您的应用程序。

对于任何会说FCGISCGI或AJP的Web服务器,Flup是与WSGI一起运行的另一种方式。根据我的经验,只有FCGI确实有效,并且可以通过mod_fastcgi在Apache中使用它,或者可以通过mod_proxy_fcgi运行单独的Python守护程序。

WSGI是与CGI非常相似的协议,它定义了一组Web服务器和Python代码如何交互的规则,其定义为Pep333。这使得许多不同的Web服务器可以使用同一应用程序协议来使用许多不同的框架和应用程序。这是非常有益的,并使其非常有用。


3
在CGI上运行WSGI是为了“通量”吗?flup如何连接到该方案?
伊莱·班德斯基

7

如果您不清楚这个领域中的所有术语,并且让我们直面它,这是一个令人困惑的首字母缩写词,那么还有一个很好的背景阅读器,形式为官方python HOWTO,其中讨论了CGI,FastCGI,WSGI等。上:http : //docs.python.org/howto/webservers.html


2
URL是过时的,我认为这是一个更新:docs.python.org/2.7/howto/webservers.html
斯特凡

很棒的材料:)应该阅读这份官方介绍以及可接受的答案。
里克

4

这是用于Python的简单抽象层,类似于Servlet规范用于Java。尽管CGI确实是低级的,只是将内容转储到流程环境和标准输入/输出中,但是以上两个规范将http请求和响应建模为该语言的构造。但是,我的印象是,在Python中,人们还不太习惯实际的实现,因此您混合使用了参考实现和其他提供WSGI支持(例如Paste)的实用程序类型的库。当然,我可能是错的,我是Python的新手。“网络脚本”社区正从不同的方向提出问题(共享托管,CGI旧版,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.