【发布时间】:2017-07-04 00:02:15
【问题描述】:
我的 API 使用 Django REST 框架,nginx 作为反向代理,redis 用于缓存一些静态 api 数据。
我试图用Cache-Control: max-age 和Last-Modify 标头实现缓存。
简而言之,它看起来像这样:
class SomeViewSet(viewsets.ModelViewSet):
....
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
cache_key = self._get_cache_key() # get a key for reddis
response = self._get_data_from_cache(cache_key) # get a data from reddis
if response:
# If data in redis return Response with a same Last-Modify
# and 'Cache-Control': 'max-age=120'
return response
# Setting up new value for this viewset in a reddis
serializer = self.get_serializer(queryset, many=True)
now = datetime.datetime.now()
cache.set(cache_key, [now, serializer.data])
return Response(serializer.data, headers={'Last-Modified': now, 'Cache-Control': 'max-age=120'})
它像我预期的那样工作,浏览器缓存数据 120 秒,当它过期时,客户端检查带有 If-Modified-Since 标头的内容。
但是我虽然在设置max-age 标头时,nginx 会将其保存在缓存文件夹中,并且会在不访问服务器的情况下为所有客户端提供服务。
这是我在本地机器上测试的 nginx 配置:
upstream django {
server 127.0.0.1:8002;
}
proxy_cache_path /home/ivan/projects/kors/test_prod/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 8000;
server_name 127.0.0.1; #
charset utf-8;
client_max_body_size 75M;
location /media {
alias /path/to/media;
expires 1y;
log_not_found off;
access_log off;
}
location /static {
alias /path/to/static;
expires 1y;
log_not_found off;
access_log off;
}
location / {
uwsgi_pass django;
include /path/to/uwsgi_params;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
proxy_cache my_cache;
}
}
考虑这篇文章nginx-caching-guide。
NGINX 如何确定是否缓存某些内容?
默认情况下,NGINX 尊重来自源服务器的 Cache‑Control 标头。它不会缓存将 Cache‑Control 设置为 Private、No‑Cache 或 No‑Store 或在响应标头中使用 Set‑Cookie 的响应。 NGINX 只缓存 GET 和 HEAD 客户端请求。您可以按照以下答案中的说明覆盖这些默认值。
我认为Cache-Contol: max-age 标头会强制 nginx 将 json 保存在缓存文件夹中。
文件夹已创建,但此处没有数据,我来自不同浏览器的所有请求都在访问服务器。
我错过了什么?或者也许我完全误解了使用 nginx 进行缓存的概念?
【问题讨论】: