Django + WSGI:令人耳目一新的问题?

时间:2009-10-28 09:06:04

标签: django apache mod-wsgi

我正在开发一个Django网站。我在实时服务器上进行了所有更改,只是因为它更容易。问题是,它偶尔似乎要缓存我正在处理的* .py文件之一。有时,如果我点击了很多次刷新,它会在较旧版本的页面和较新版本之间来回切换。

我的设置或多或少与Django教程中描述的一样:http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/#howto-deployment-modwsgi

我正在猜测它正在执行此操作,因为它启动了WSGI处理程序的多个实例,并且根据http请求发送到哪个处理程序,我可能会收到不同版本的页面。重启apache似乎解决了这个问题,但这很烦人。

我真的不太了解WSGI或“MiddleWare”或任何请求处理的东西。我来自PHP背景,它只是工作:)

无论如何,解决这个问题的好方法是什么?运行WSGI处理程序是“守护进程模式”可以缓解这个问题吗?如果是这样,我如何让它以守护进程模式运行?

4 个答案:

答案 0 :(得分:17)

以守护进程模式运行进程无济于事。这是正在发生的事情:

mod_wsgi正在生成多个相同的进程来处理Django站点的传入请求。这些进程中的每一个都是自己的Python解释器,可以处理传入的Web请求。这些进程是持久的(它们不会针对每个请求启动和拆除),因此单个进程可以一个接一个地处理数千个请求。 mod_wsgi能够同时处理多个Web请求,因为有多个进程。

每当执行“导入模块”时,每个进程的Python解释器都会加载您的模块(您的自定义Python文件)。在django的上下文中,当由于Web请求而需要新的view.py时会发生这种情况。加载模块后,它将驻留在内存中,因此您对该文件所做的任何更改都不会反映在该进程中。随着更多的Web请求进入,进程的Python解释器将只使用已经加载到内存中的模块版本。您发现刷新之间存在不一致,因为您正在进行的每个Web请求都可以由不同的进程处理。某些进程可能在您的代码的早期版本中加载了您的Python模块,而其他进程可能稍后加载了它们(因为这些进程没有收到Web请求)。

简单的解决方案:无论何时修改代码,都要重新启动Apache进程。大多数时候就像从shell“/etc/init.d/apache2 restart”以root身份运行一样简单。我相信一个简单的重载也可以,速度更快,“/ etc / init.d / apache2 reload”

守护进程解决方案:如果您在守护进程模式下使用mod_wsgi,那么您需要做的就是触摸(unix命令)或修改您的wsgi脚本文件。为了澄清scrompt.com的帖子,对Python源代码的修改不会导致mod_wsgi重新加载代码。仅在修改wsgi脚本文件时才会重新加载。

最后一点需要注意:为了简单起见,我只是将wsgi称为使用进程。 wsgi实际上在每个进程中使用线程池。我觉得这个细节与此答案无关,但您可以通过阅读mod_wsgi了解更多信息。

答案 1 :(得分:5)

因为您在嵌入模式下使用mod_wsgi,所以您的更改不会自动显示。你偶尔会看到它们,因为Apache有时会启动新的处理程序实例,这会抓住更新。

您可以使用守护程序模式解决此问题,如here所述。具体来说,您需要将以下指令添加到Apache配置中:

WSGIDaemonProcess example.com processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup example.com

答案 2 :(得分:5)

阅读mod_wsgi文档,而不是依赖于Django站点上包含的mod_wsgi托管的最小信息。在部分内容中,请阅读:

http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

这告诉你源代码重新加载在mod_wsgi中是如何工作的,包括一个监视器,你可以使用它来实现Django runserver所做的相同类型的源代码重新加载。另请参阅哪些有关如何将其应用于Django的讨论。

http://blog.dscpl.com.au/2008/12/using-modwsgi-when-developing-django.html   http://blog.dscpl.com.au/2009/02/source-code-reloading-with-modwsgi-on.html

答案 3 :(得分:2)

您可以通过不在实时服务器上编辑代码来解决此问题。说真的,没有任何借口。使用版本控制进行本地开发,如果必须,可以通过实时结帐运行服务器,使用提交后挂钩检查最新版本并重新启动Apache。