Python Web 框架、 WSGI 和 CGI 是如何结合在一起的

我有一个 蓝主机帐户,在那里我可以运行 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樱桃) ,我需要知道、安装和做什么?如何安装 WSGI 支持?

47821 次浏览

你可以以 像 Pep333演示的那样在 CGI 上运行 WSGI为例。然而,每当有一个请求时,就会启动一个新的 Python 解释器,并且需要构建整个上下文(数据库连接等) ,这都需要时间。

如果您想运行 WSGI,最好的办法是您的主机安装 Mod _ wsgi并进行适当的配置,以便将控制权交给您的应用程序。

对于任何能说 FCGISCGI或 AJP 语言的网络服务器,Flup 是另一种使用 WSGI 运行的方式。根据我的经验,只有 FCGI 真正起作用,它可以通过 Mod _ fastcgi在 Apache 中使用,也可以通过 Mod _ xy _ fcgi运行单独的 Python 守护进程。

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

我认为 Florian 的回答回答了你关于“什么是 WSGI”的部分问题,特别是当你阅读 PEP的时候。

至于你最后提出的问题:

WSGI、 CGI、 FastCGI 等都是 Web 服务器到 运行代码的协议,并提供生成的动态内容。将其与静态 Web 服务相比较,静态 Web 服务基本上是将一个普通的 HTML 文件传递给客户端。

CGI、 FastCGI 和 SCGI 是语言无关的。你可以用佩尔、 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 服务器(如 樱桃)。如果这两者都不可能,那么 可以将使用 PEP 中提供的 CGI-WSGI 桥。

这是 Python 的一个简单抽象层,类似于 Java 的 Servlet 规范。尽管 CGI 级别很低,只是将内容转储到流程环境和标准的 in/out 中,但是上面两个规范将 http 请求和响应建模为语言中的构造。然而,我的印象是,在 Python 中,人们还没有完全确定事实上的实现,所以你有一个混合的引用实现,以及其他实用程序类型的库,它们提供了 WSGI 支持(例如粘贴)的其他东西。当然我可能错了,我是 Python 的新手。“ web 脚本”社区正在从不同的方向来解决这个问题(共享主机、 CGI 遗留问题、权限分离问题) ,而不是像 Java 社区的人们那样奢侈地开始(在一个专门的环境中运行一个企业容器,而不是静态编译和部署代码)。

WSGI、 CGI 和框架之间是如何连接的?

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

对于 CGI,Apache 准备一个环境并通过 CGI 协议调用脚本。这是一个标准的 Unix Fork/Exec 情况—— CGI 子进程继承一个操作系统环境,包括 socket 和 stdout。CGI 子进程写入一个响应,该响应返回到 Apache; Apache 将这个响应发送给浏览器。

CGI 是原始的和恼人的。主要是因为它为每个请求分支一个子进程,子进程必须退出或关闭 stdout 和 stderr 以表示响应结束。

WSGI 是一个基于 CGI 设计模式的接口。它不一定是 CGI ——它不必为每个请求分支一个子进程。它可以是 CGI,但不一定是。

WSGI 以几种重要的方式添加到 CGI 设计模式中。它为您解析 HTTP 请求头并将它们添加到环境中。它提供任何面向 POST 的输入作为环境中类似文件的对象。它还为您提供了一个函数,该函数将规划响应,从而避免了大量格式化细节。

如果我想在我的基本 CGI 配置上运行一个 web 框架(比如 web.py 或者 cherrypy) ,我需要知道/install/做什么?

回想一下分叉子进程的开销是很大的,有两种方法可以解决这个问题。

  1. 嵌入式 mod_wsgimod_python将 Python 嵌入到 Apache 中; 没有分支进程,Apache 直接运行 Django 应用程序。

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

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

当您阅读 mod _ fastcgi 时,您将看到 Django 使用 一团糟根据 mod _ fastcgi 提供的信息创建与 WSGI 兼容的接口。管道是这样运作的。

Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)

Django 为各种接口提供了几个“ Django.core.handlers”。

对于 mod _ fastcgi,Django 提供了一个集成了 FLUP 和处理程序的 manage.py runfcgi

对于 mod _ wsgi,有一个用于此目的的核心处理程序。

如何安装 WSGI 支持?

按照这些指示做。

Https://code.google.com/archive/p/modwsgi/wikis/integrationwithdjango.wiki

有关背景资料,请参阅

Http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index

如果你不清楚这个空间中的所有术语,让我们面对它,这是一个令人困惑的首字母缩略词,还有一个很好的背景阅读器的形式,官方的 Python HOWTO 讨论 CGI VS 快速 CGI VS WSGI 等等: http://docs.python.org/howto/webservers.html