【问题标题】:How I can force nginx to save response in a cache folder, with headers from upstream server?如何强制 nginx 使用上游服务器的标头将响应保存在缓存文件夹中?
【发布时间】:2017-07-04 00:02:15
【问题描述】:

我的 API 使用 Django REST 框架,nginx 作为反向代理,redis 用于缓存一些静态 api 数据。
我试图用Cache-Control: max-ageLast-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 进行缓存的概念?

【问题讨论】:

    标签: django caching nginx


    【解决方案1】:

    首先打电话给你在标题中添加一个Cache-Control: max-age 不会告诉 nginx 对它做任何事情。客户端管理如何处理标头以及如何处理后续请求。

    您可能是 nginx 对 url 的响应缓存。你的 nginx 配置没有这样的问题。

    uwsgi_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;
    
    location / {
    
        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;
    
        uwsgi_cache my_cache;
        uwsgi_pass  django;
    }
    

    你需要在这里使用 uwsgi 缓存模块。

    看这里http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html

    【讨论】:

    • 谢谢!缓存现在保存,但是如果所有新客户端都命中上游服务器,那么缓存的意义何在?对不起,如果我完全误解了一个概念。我认为会是New client come -> hit a server -> nginx saves cache for 120 sec -> client get a response,然后在 120 秒内调用该资源的所有新客户端从 nginx 缓存中获取它。我认为reverse proxy 的意思正是我上面所描述的。
    • 这是预期的行为。你看到的不一样吗?
    • 不,我在我的视图中打印了代码,以确保服务器正在运行。当我在 Chrome 中提供第一个请求时,服务器会命中,然后 Chrome 中的下一个请求不会命中服务器。但是,当我在 max-age 未过期时从 Firefox 发送请求时,服务器再次受到攻击。
    • 你能看看wsgi忽略标题nginx.org/en/docs/http/…
    • uwsgi_ignore_headers "Vary"; 似乎使它正常工作,非常感谢。但我没有得到一个,“首先打电话给你在标题中添加一个 Cache-Control: max-age 并没有告诉 nginx 对它做任何事情”。如果没有提供该标头,nginx 将不会将该资源中的数据保存在缓存中。
    猜你喜欢
    • 2020-05-02
    • 2018-03-10
    • 1970-01-01
    • 2016-08-14
    • 2022-01-06
    • 2011-07-06
    • 1970-01-01
    • 2017-07-01
    • 2017-08-19
    相关资源
    最近更新 更多