我一直认为每个站点缓存在到期之前不会更新,而其他人thought so也是如此。但是我在网站上做了一些测试后发现了不同的结果。正如您所见,My website是一个典型的博客。
以下是我测试它的方式:
使用awk '{while(sub(/%[0-9]+/,"{"x++"}"));}!(x=0)' file
启动memcached,以便我可以看到memcached中发生了什么。
然后做了一些操作:
访问主页 - >访问主页 - >更新主页上的文章 - >访问主页
缓存中没有存储任何缓存存储(奇怪!)
我的上一次访问确实更新了主页。
我的缓存过期时间是600s,所以我可以向你保证第二次缓存存储操作与缓存过期无关。(实际上我重复了几次,都给出了相同的结果)。
那么对此有何解释? documentaion没有提供太多信息。或者是因为我以错误的方式进行了测试?
答案 0 :(得分:2)
您可以在中间件UpdateCacheMiddleware中查找process_response
的源代码来弄清楚:
def process_response(self, request, response):
"""Sets the cache, if needed."""
if not self._should_update_cache(request, response):
# We don't need to update the cache, just return.
return response
if response.streaming or response.status_code != 200:
return response
# Don't cache responses that set a user-specific (and maybe security
# sensitive) cookie in response to a cookie-less request.
if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'):
return response
# Try to get the timeout from the "max-age" section of the "Cache-
# Control" header before reverting to using the default cache_timeout
# length.
timeout = get_max_age(response)
if timeout is None:
timeout = self.cache_timeout
elif timeout == 0:
# max-age was set to 0, don't bother caching.
return response
patch_response_headers(response, timeout)
if timeout:
cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
if hasattr(response, 'render') and callable(response.render):
response.add_post_render_callback(
lambda r: self.cache.set(cache_key, r, timeout)
)
else:
self.cache.set(cache_key, response, timeout)
return response
首先检查您的博客是否旨在让经过身份验证的用户,因为它因if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie')
而无法正常工作。
如果未经过身份验证,则必须查看learn_cache_key
方法,该方法计算将缓存视图的密钥:
def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None):
"""
Learns what headers to take into account for some request URL from the
response object. It stores those headers in a global URL registry so that
later access to that URL will know what headers to take into account
without building the response object itself. The headers are named in the
Vary header of the response, but we want to prevent response generation.
The list of headers to use for cache key generation is stored in the same
cache as the pages themselves. If the cache ages some data out of the
cache, this just means that we have to build the response once to get at
the Vary header and so at the list of headers to use for the cache key.
"""
if key_prefix is None:
key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
if cache_timeout is None:
cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
cache_key = _generate_cache_header_key(key_prefix, request)
if cache is None:
cache = caches[settings.CACHE_MIDDLEWARE_ALIAS]
if response.has_header('Vary'):
is_accept_language_redundant = settings.USE_I18N or settings.USE_L10N
# If i18n or l10n are used, the generated cache key will be suffixed
# with the current locale. Adding the raw value of Accept-Language is
# redundant in that case and would result in storing the same content
# under multiple keys in the cache. See #18191 for details.
headerlist = []
for header in cc_delim_re.split(response['Vary']):
header = header.upper().replace('-', '_')
if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant:
continue
headerlist.append('HTTP_' + header)
headerlist.sort()
cache.set(cache_key, headerlist, cache_timeout)
return _generate_cache_key(request, request.method, headerlist, key_prefix)
else:
# if there is no Vary header, we still need a cache key
# for the request.build_absolute_uri()
cache.set(cache_key, [], cache_timeout)
return _generate_cache_key(request, request.method, [], key_prefix)
请注意,Django会深入研究response['Vary']
标题,并会为其添加键的关键变体。
因此,请检查您的回复是否添加了Vary
标题,如果是,那么它具有哪个值,如果它与保存条目之前不同,那么您将解释为什么不进行缓存。
另请注意,如果激活多语言,它还会为每种语言生成不同的键。
当Django添加或修改Vary
标题时
在这里,您可以看到它何时发生或在docs中如何发生以及如何在视图here中控制缓存。
最后考虑到,如果您为博客使用第三方应用,则可能会使用缓存控制机制在更改数据(如更新条目)时刷新缓存。
Django版
在Django> = 1.7使用完全限定的网址,因此如果您使用这些版本也会考虑HOSTS:
在Django 1.7中更改: 缓存键使用请求的完全限定URL,而不仅仅是路径和查询字符串。
答案 1 :(得分:-1)
好吧,原来我的测试有问题。当没有其他人访问我的网站时,我再次仔细测试。这是memcached -vv
的输出:
# first visit
<30 new auto-negotiating client connection
30: Client using the ascii protocol
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST
>30 END
<30 set :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 1 600 14
>30 STORED
<30 set :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 1 600 33215
>30 STORED
<30 connection closed.
# second visit
<30 new auto-negotiating client connection
30: Client using the ascii protocol
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST
>30 sending key :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST
>30 END
<30 get :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST
>30 sending key :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST
>30 END
<30 connection closed.
# modified and save
<30 new auto-negotiating client connection
30: Client using the ascii protocol
<30 get :1:views.decorators.cache.cache_header..7029e9375fc4657a73dae1f9bddb73e5.en-us.CST
>30 END
<30 connection closed.
# visit again
<30 new auto-negotiating client connection
30: Client using the ascii protocol
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST
>30 sending key :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST
>30 END
<30 get :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST
>30 sending key :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST
>30 END
<30 connection closed.
此输出显示memcached正在按预期工作。我不确定以前输出的解释是什么。