Nginx 缓存失效仅当从同一域调用时才有效

Nginx 缓存失效仅当从同一域调用时才有效

我正在使用 FRiCKLE 的 ngx_cache_purge 模块来使代理缓存失效。我遇到了一个问题,即当访问失效 URL 时,如果 URL 的 HOST 部分与用于访问原始内容的 URL 不同,则无法清除缓存。例如,如果我像这样访问内容:

curl -H 'Content-Type: application/json' -d '{ "token": "pts7v4nqf7stfq35qeb570v5n2" }' -X POST -D - http://api.example.com/news/article/cache-testing

缓存文件使用正确的密钥创建,并且能够正常工作,后续请求可以正确处理。当内容发生变化时,为了清除缓存数据,后端会在所有 Web 服务器上执行相同的操作:

curl -D - http://10.200.100.101:8080/invalidate_cached_url/POST/news/article/cache-testing

这会返回 404,因为缓存文件是host在考虑 URL 的一部分的情况下生成的,为了清除它,我必须使用相同的主机调用失效 URL。这是一个问题,因为我在 Webstack 前面有一个负载均衡器。

为了证明这一点,我保存了用上述方法生成的缓存文件并清除了缓存,然后直接用IP地址访问了api端点:

curl -H 'Content-Type: application/json' -d '{ "token": "pts7v4nqf7stfq35qeb570v5n2" }' -X POST -D - http://10.200.100.101:8080/news/article/cache-testing

现在,当我尝试像上面那样清除缓存时,它起作用了。确实,缓存文件不同,但在二进制级别上,但键是相同的。

有没有解决的办法?

这是我的配置:

proxy_cache_path /tmp/nginx/example-api levels=1:2 keys_zone=example_api_zone:300m inactive=1h;

upstream origin_api {
    server localhost:8888;
}

server {
    listen 8080 default_server;
    server_name  api.example.com;

    proxy_buffering on;
    proxy_buffer_size 1k;
    proxy_buffers 24 4k;
    proxy_busy_buffers_size 8k;
    proxy_max_temp_file_size 2048m;
    proxy_temp_file_write_size 32k;

    proxy_cache_key $request_method$uri;

    access_log /var/log/nginx/example-api.access.log;
    error_log /var/log/nginx/example-api.error.log;

    error_page 500 502 /502.html;
    location = /502.html {
      internal;
      root /opt/errors;
    }

    location / {
      gzip on;
      include example_proxy_params.conf;
      proxy_cache_bypass $http_cache_control;
      proxy_cache_methods POST GET;
      proxy_pass http://origin_api;
    }

    location ~ ^/news/singlearticle/ {
      gzip on;
      proxy_hide_header Cache-Control;
      add_header Cache-Control 'max-age=10s, no-cache ,public';
      include example_proxy_params.conf;
      proxy_cache_bypass $http_cache_control;
      proxy_cache_methods POST GET;
      proxy_pass http://origin_api;
    }

    location ~ ^/news/subcategory/ {
      proxy_cache_key "$request_method$request_uri|$request_body";
      include example_proxy_params.conf;
      proxy_cache_bypass $http_cache_control;
      proxy_cache_methods POST GET;
      proxy_pass http://origin_api;
    }

    location ~ /invalidate_cached_url/(.*) {
      allow 127.0.0.1;
      allow 10.200.100.101;
      allow 10.200.100.102;
      deny all;
      proxy_cache_purge example_api_zone $1;
    }

}

答案1

在命令中设置主机名curl,例如:

curl -H "Host: api.example.com" -D - http://192.168.255.230:8080/invalidate_cached_url/....

答案2

事实证明,解决方案是添加一个Origin标头,因为 nginx 实际上使用它来创建哈希文件,而且如果你仔细想想,它确实很有意义。这在任何允许的 IP 上都可以成功:

curl -H 'Origin: http://testing.bktvnews.com' -D - http://10.200.100.101:8080/invalidate_cached_url/POST/news/article/cache-testing

相关内容