你如何部署WSGI应用程序?(以及为什么这是最佳方式)

42

我正在部署一个WSGI应用程序。有很多方法可以实现。我目前正在使用带有mod-wsgi的apache2,但我可以看到一些潜在的问题。

那么怎么做呢?

  1. Apache Mod-wsgi(其他mod-wsgi似乎不值得使用)
  2. 纯Python Web服务器,如paste、cherrypy、Spawning、Twisted.web
  3. 像nginx、apache2等那样进行反向代理,并具有良好的静态文件处理,类似于第2种方法
  4. 将其转换为其他协议,如通过桥接器(例如Flup)转换为FCGI,并在传统Web服务器中运行。

还有更多吗?

我想知道您是如何做到这一点的,以及为什么这是最好的方法。我非常喜欢您能详细地讲解有关应用程序的事情,包括其特定内容等。


你能澄清一下吗?部署是将代码放入环境中的行为,而不是选择mod_wsgi还是cherrypy。它涉及升级、安装、推送到多个服务器等操作;而不仅仅是重新启动apache或运行easy_install。 - Richard Levasseur
8
Richard:部署是一种选择和行动。 - Ali Afshar
9个回答

26

一如既往:这要看具体情况而定 ;-)

当我不需要任何apache功能时,我会选择像paste等纯python web服务器。哪个服务器最适合你的应用程序取决于你的具体需求,并且可以通过进行一些基准测试来确定。我一直想做一些基准测试,但从未实现过。我猜Spawning可能在使用非阻塞IO方面具有一些优势,但由于它正在打补丁,所以有时会遇到问题。

当然,您始终可以在前面放一个varnish。

如果需要Apache,我通常会采用解决方案3,以便保持进程分离。您还可以更轻松地将进程移动到其他服务器等。我只是喜欢事情分开来。

对于静态文件,我目前正在为一个项目使用单独的服务器,该服务器只提供静态图像/ css / js。我正在使用lighttpd作为web服务器,它具有出色的性能(在这种情况下,我不再需要varnish)。

另一个有用的工具是 supervisord ,用于控制和监视这些服务。

我还使用 buildout 来管理我的部署和开发沙箱(与 virtualenv 一起)。


13

我真的很想让你详细介绍一下什么是什么,为什么要这样做,应用程序特定内容等等。

好的,你要求了!

像Daniel一样,我个人使用带有mod_wsgi的Apache。在某些环境中部署它仍然很新颖,可能会遇到一些困难,但如果您已经自己编译所有东西,那么它就非常容易。我发现它非常可靠,即使是早期版本也是如此。感谢Graham Dumpleton几乎独立地控制了它。

然而,对于我来说,WSGI应用程序必须在所有可能的服务器上工作。目前在这个领域还存在一些问题:您有WSGI标准告诉您WSGI可调用项(应用程序)的功能,但没有部署的标准化;没有一种单一的方法告诉Web服务器如何找到应用程序。同时也没有一种标准的方法在更新应用程序后重新加载应用程序。

我采用的方法是:

  • 将所有应用程序逻辑放在模块/包中,最好是类中

  • 通过子类化主要应用程序并覆盖成员来完成所有特定于网站的自定义

  • 将所有特定于服务器的部署设置(例如数据库连接工厂,邮件中继设置)作为class __init__()参数

  • 一个顶层'application.py'脚本,使用当前服务器的正确部署设置初始化Application类,然后以一种使其可以作为CGI脚本、mod_wsgi WSGIScriptAlias(或Passenger,它显然是以相同的方式工作)部署,或者可以从命令行交互的方式运行应用程序。

  • 一个帮助器模块,处理上述部署问题,并允许在应用程序所依赖的模块更改时重新加载应用程序

因此,最终的application.py看起来像:

#!/usr/bin/env python

import os.path
basedir= os.path.dirname(__file__)

import MySQLdb
def dbfactory():
    return MySQLdb.connect(db= 'myappdb', unix_socket= '/var/mysql/socket', user= 'u', passwd= 'p')

def appfactory():
    import myapplication
    return myapplication.Application(basedir, dbfactory, debug= False)

import wsgiwrap
ismain= __name__=='__main__'
libdir= os.path.join(basedir, 'system', 'lib')
application= wsgiwrap.Wrapper(appfactory, libdir, 10, ismain)

wsgiwrap.Wrapper每10秒钟检查一次libdir中的应用程序模块是否已更新,如果有更新,则使用一些麻烦的sys.modules魔术可靠地卸载所有模块。然后再次调用appfactory()以获取更新的应用程序的新实例。

(您还可以使用命令行工具,例如

./application.py setup
./application.py daemon

运行应用程序提供的任何设置和后台任务钩子 callable,有点类似于 distutils 的工作方式。它还响应像 init 脚本一样的启动/停止/重启命令。

我使用的另一个技巧是将多个服务器的部署设置(开发/测试/生产)放在同一个 application.py 脚本中,并嗅探 'socket.gethostname()' 来决定使用哪个特定于服务器的一堆设置。

在某些时候,我可能会打包 wsgiwrap 并正式发布它(可能使用不同的名称)。同时,如果您有兴趣,您可以在 http://www.doxdesk.com/file/software/py/v/wsgiwrap-0.5.py 查看 dogfood-development 版本。


6
无法保证在所有情况下都能100%可靠地进行模块重载。唯一安全的方法是重新启动进程。因此,如果您确实想要在开发中使用此类技巧,请使用,但在生产系统中永远不要依赖它们。 - Graham Dumpleton

13

部署最简单的是CherryPy,你的Web应用程序也可以成为独立的Web服务器。考虑到CherryPy是纯Python编写的,它也是一个相当快的服务器。话虽如此,它并不是Apache。因此,我认为CherryPy是较低流量Web应用程序的不错选择。

除此之外,我认为对于这个问题没有绝对的对与错。许多高流量的网站都是使用你所提到的技术构建的,我认为你不会在任何一种方式上走太错(尽管我同意mod-wsgi不适用于每个非Apache服务器)。

此外,我一直在使用isapi_wsgi在IIS下部署Python应用程序。这是一个不太理想的设置,但它能工作,当你生活在以Windows为中心的世界时,你不总能选择其他方式。


6
Nginx反向代理和静态文件共享+XSendfile+uploadprogress_module。对于此目的,无与伦比。
在WSGI方面,使用Apache + mod_wsgi或cherrypy服务器。我喜欢在内存较少、请求数较少的服务器上使用cherrypy wsgi服务器进行应用程序。
推理:
我已经使用不同的工具对不同的流行解决方案进行了基准测试。
我对TCP/IP的低级别有更多的经验,而不是Web开发,特别是HTTP实现。我更有信心能够识别出一个好的HTTP服务器,而不是识别出一个好的Web框架。
我比Django或Pylons更了解Twisted。 Twisted中的HTTP堆栈仍未达到要求,但它将会到达。

4

我正在开发一个应用程序,使用谷歌应用引擎。它可以运行WSGI应用程序。 这里有一些相关信息。

这是我第一次真正参与的Web应用程序,所以我没有什么可比较的基础,但如果你是谷歌粉丝,你可能会想要研究一下它。我很享受将其作为我的学习框架所带来的乐趣。


4

TurboGears (2.0)

TurboGears 2.0将在接下来的一个月内推出正式版(已经进行了相当长时间的测试)。2.0版本改进了1.0系列,并试图为您提供最佳的WSGI堆栈,因此如果您想要最少的麻烦,它会为您做出一些默认选择。

它具有1.x系列中用于测试和部署的tg*工具,但现在转换为2.0系列中的paster等效工具,如果您尝试过pylons,那么这些工具应该很熟悉。

tg-admin quickstart —> paster quickstart
tg-admin info —> paster tginfo
tg-admin toolbox –> paster toolbox
tg-admin shell –> paster shell
tg-admin sql create –> paster setup-app development.ini

Pylons

如果您希望在WSGI堆栈(ORM选择、模板引擎选择、表单处理选择)方面更加灵活,Pylons成为了不错的选择。这是我推荐的选择,因为它提供了优秀的文档,并允许您尝试不同的组件。

因此,结果是非常好用的,并且可以在Apache(生产部署)或独立模式下工作(有助于测试和实验阶段)。

所以,您可以在Pylons中同时做到以下两点:

  • 2个选项用于测试阶段(python独立模式)

  • 4个选项用于可扩展的生产目的(FastCGI,假设您选择的数据库可以跟上)

Pylons管理界面与TurboGears非常相似。这是一个玩具独立模式示例:

$ paster create -t pylons helloworld
$ cd helloworld
$ paster serve --reload development.ini

对于生产级别的部署,您可以参考此处提供的Apache + FastCGI + mod_rewrite设置指南(英文)。这将适用于大多数需求。


3

使用web.py(一个wsgi应用程序)的Apache httpd + mod_fcgid非常顺利。

运行得很好。


1
我们在一些网络服务中使用纯粹的Paste。它很容易部署(通过我们内部的部署机制;我们没有使用Paste Deploy或类似的东西),并且能够很好地减少生产系统与开发人员工作站之间的差异。需要注意的是,由于我们请求的繁重性质,我们不指望Paste本身具有低延迟。在我们进行了一些简单的基准测试后,我们并没有得到“极好”的结果;但由于我们典型请求处理程序的开销,这个问题最终变得无关紧要。到目前为止,它一直运行良好。
静态数据已经通过完全独立(并且有点“有机”成长)的堆栈来处理,包括使用S3、Akamai、Apache和IIS以各种方式。

1

Apache+mod_wsgi,

简单、干净(只有四行Web服务器配置),易于其他系统管理员理解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接