如何禁用Django/mod_WSGI页面缓存

11

我在使用mod_wsgi将Django运行在Apache上。我认为Django正在对我的页面进行服务器端缓存,这导致某些功能无法正确工作。

我有一个倒计时计时器,它通过获取当前服务器时间,确定剩余的倒计时时间,并输出该数字到HTML模板来工作。然后,JavaScript倒计时计时器接管并为用户运行倒计时。

问题出现在用户刷新页面或导航到具有倒计时计时器的不同页面时。计时器似乎会跳到不同的时间,通常在每次刷新时都会回到相同的时间。

使用HTTPFox,页面没有从我的浏览器缓存中加载,因此看起来Django或Apache正在缓存页面。有没有办法禁用这个功能?我不需要担心缓存脚本输出的流量不足。还是我完全错了原因?

[编辑] 从下面的帖子中,看起来Django已禁用缓存,这意味着它必须在其他地方发生,也许是在Apache中?

[编辑] 我更详细地描述一下正在发生的事情:对于向服务器发出的前7个(左右)请求,页面由脚本呈现并返回,尽管这7个页面中的每一个似乎都被缓存了,因为稍后会显示出来。在第8个请求上,服务器提供第一个页面。在第9个请求上,它提供第二个页面,等等循环。这将持续到我重新启动Apache,然后过程重新开始。

[编辑] 我已经配置mod_wsgi只运行一个进程,这导致计时器在每种情况下都重置为相同的值。有趣的是,我的页面上还有另一个组件,它在每次请求中使用order('?') 显示不同的随机图像,并且每次都会刷新,这表明缓存是在Django中而不是在Apache中发生。

[编辑] 根据之前的编辑内容,我回去重新审查了相关的views.py文件,发现倒计时开始变量是在模块全局范围内设置的,而不是在视图函数内。将该设置移到视图函数内部解决了问题。因此,结果并不是缓存问题。感谢大家对此帮助。


http://www.djangobook.com/en/2.0/chapter15/ - cwallenpoole
4个回答

8
根据我在Apache中使用mod_wsgi的经验,它极不可能导致缓存。尝试以下几点:
  1. 你的电脑和Web服务器之间可能有一些代理服务器,它们会适当或不适当地缓存页面。有时,ISP运行代理服务器以减少其网络外的带宽。请提供一个被缓存的页面的HTTP头信息(Firebug可以提供这些信息)。我特别关注的头信息包括Cache-Control、Expires、Last-Modified和ETag。
  2. 可以在settings.py文件中发布MIDDLEWARE_CLASSES吗?可能你有一个执行缓存的中间件。
  3. 在你的代码中搜索以下项“load cache”、“django.core.cache”和“cache_page”。*grep -R "search" **将起作用。
  4. settings.py(或任何它导入的内容,如“from localsettings import *”)是否包括CACHE_BACKEND?
  5. 当你重新启动Apache时会发生什么?(例如sudo services apache restart)。如果重新启动可以清除问题,则可能是Apache进行了缓存(这也可能清除locmen Django缓存后端)。

我同意。很可能是Apache或你的ISP在进行缓存。 - Paul McMillan
  1. 该网站目前运行在我们本地网络上的服务器上,因此没有代理。
  2. MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', )
  3. 这些术语在代码中任何地方都没有出现。
  4. 不是。
  5. 重新启动Apache可以清除问题并刷新缓存到新值。
- Travis

2
我刚看到这个:

自动重新加载支持为了帮助部署工具,您可以激活对自动重新加载的支持。每当.wsgi文件发生更改时,mod_wsgi将为我们重新加载所有守护进程。

为此,请将以下指令添加到您的目录部分:

WSGIScriptReloading On

2
这是默认开启的,所以你不必担心它。有关如何处理重新加载的信息,请参见http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode。 - Graham Dumpleton
2
我不知道 - 但我可以说我在两台不同的机器上使用了wsgi - 其中一台是基于Django的复杂网站(OpenStack Dashboard / Horizon),另一台是我的自己编写的简单脚本 - 在每个上启用WSGIScriptReloading,这样当我修改脚本时,下一页重新加载时修改将生效,而无需重新启动Apache。 - Brad
2
我可以说我编写了mod_wsgi,代码默认启用它。正如我链接的文档中所解释的那样,对于嵌入模式,WSGI脚本文件本身会重新加载,而不是所有应用程序代码。您应该仔细检查自己是否实际上正在使用文档描述的嵌入式模式或守护进程模式。很多情况下,人们没有WSGIProcessGroup指令,他们认为自己正在使用守护程序模式,但事实并非如此。 - Graham Dumpleton

2

您是否特别设置了Django缓存?从文档中可以看出,在使用前需要进行一些工作才能使其生效,因此您应该清楚地知道Django是否正在进行缓存。具体而言,您需要定义缓存文件的保存位置。

http://docs.djangoproject.com/en/dev/topics/cache/


我没有做任何预备工作,所以我猜测Django缓存被禁用了...还有什么其他原因可能导致计时器启动时间被缓存?是Apache和mod_wsgi在起作用吗? - Travis

2
您是否在使用Apache/mod_wsgi的多进程配置?如果是这样,那么不同的响应之间计时器的值不同可能是因为每个处理请求的进程初始化计时器的时间不同。这就是为什么它会跳来跳去的原因。
请阅读:

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

请说明您正在运行的Apache/mod_wsgi模式或配置,并可能发布该配置。如果不知道,那么就会有太多未知因素。

httpd -V 显示正在使用 Prefork MPM。 线程化:否,分叉:是(可变进程计数) - Travis
然后,不同的进程可以处理不同的请求,因此这些进程可能具有数据的不同视图。此外,请阅读“http://blog.dscpl.com.au/2009/03/load-spikes-and-excessive-memory-usage.html”,了解在使用mod_python和mod_wsgi的prefork时存在的危险。 - Graham Dumpleton
似乎就是这样的情况。我将配置更改为以守护进程模式运行,将进程数量限制为一个,这样就只有一个缓存版本的页面了。因此,我的计时器在每个请求上都会重置为相同的值。然而,这仍然不是期望的行为。 - Travis

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