我真的很想让你详细介绍一下什么是什么,为什么要这样做,应用程序特定内容等等。
好的,你要求了!
像Daniel一样,我个人使用带有mod_wsgi的Apache。在某些环境中部署它仍然很新颖,可能会遇到一些困难,但如果您已经自己编译所有东西,那么它就非常容易。我发现它非常可靠,即使是早期版本也是如此。感谢Graham Dumpleton几乎独立地控制了它。
然而,对于我来说,WSGI应用程序必须在所有可能的服务器上工作。目前在这个领域还存在一些问题:您有WSGI标准告诉您WSGI可调用项(应用程序)的功能,但没有部署的标准化;没有一种单一的方法告诉Web服务器如何找到应用程序。同时也没有一种标准的方法在更新应用程序后重新加载应用程序。
我采用的方法是:
将所有应用程序逻辑放在模块/包中,最好是类中
通过子类化主要应用程序并覆盖成员来完成所有特定于网站的自定义
将所有特定于服务器的部署设置(例如数据库连接工厂,邮件中继设置)作为class __init__()参数
一个顶层'application.py'脚本,使用当前服务器的正确部署设置初始化Application类,然后以一种使其可以作为CGI脚本、mod_wsgi WSGIScriptAlias(或Passenger,它显然是以相同的方式工作)部署,或者可以从命令行交互的方式运行应用程序。
一个帮助器模块,处理上述部署问题,并允许在应用程序所依赖的模块更改时重新加载应用程序
因此,最终的application.py看起来像:
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 版本。