第一次请求后,Nginx ssi 与 proxy_cache 挂起

第一次请求后,Nginx ssi 与 proxy_cache 挂起

我正在使用 Nginx 的代理缓存来处理我们的动态页面,并且最近集成了 ssi。第一个页面加载工作正常,但是一旦页面被缓存并且另一个请求通过,页面就会挂起。

日志似乎表明发出了多个子请求(只有一个指令,并且位于布局中),我不太清楚为什么会发生这种情况。页面在第一次加载时加载正常,但缓存版本却停滞不前并崩溃。这是我的配置。

proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=500m inactive=60m; #caching
proxy_temp_path /var/tmp; #caching

gzip_comp_level 6;
gzip_vary on;
gzip_min_length  1000;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;

upstream staging {
  server 127.0.0.1:1337;
}

server {
  listen 0.0.0.0:80;
  server_name dev.example.com;
  access_log /var/log/nginx/dev.example.log;
  error_log  /var/log/nginx/dev.example.error.log debug;   log_subrequest on;

  location ~ ^/(images/|scripts/|styles/|robots.txt|humans.txt|favicon.ico) { #caching
    root /home/example/app/website/public;
    access_log off;
    expires modified +1h;
  }

  location / {
    ssi on;

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_cache one; #caching
    proxy_cache_key sfs$request_uri$scheme; #caching

    proxy_http_version 1.1;
    proxy_pass http://staging/; #points to the upstream staging
  }
}

这是布局中的指令

<!--# include virtual="/ssi/dynamic-content" -->

- 编辑 -

我刚刚注意到页面布局似乎也渲染了多次。ssi 请求除了 div 之外没有返回任何标记,我不确定为什么整个布局会被插入多次。

-- 编辑 2 --

我不知道为什么这样做有效,但我能够通过将 ssi 请求移出 location / {} 块并移入它们自己的块中来解决这个问题,这样可以跳过缓存设置并直接进入服务器。我的配置现在看起来像这样。

proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=500m inactive=60m; #caching
proxy_temp_path /var/tmp; #caching

gzip_comp_level 6;
gzip_vary on;
gzip_min_length  1000;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;

upstream staging {
  server 127.0.0.1:1337;
}

server {
  listen 0.0.0.0:80;
  server_name dev.example.com;
  access_log /var/log/nginx/dev.example.log;
  error_log  /var/log/nginx/dev.example.error.log debug;   log_subrequest on;

  location ~ ^/(images/|scripts/|styles/|robots.txt|humans.txt|favicon.ico) { #caching
    root /home/example/app/website/public;
    access_log off;
    expires modified +1h;
  }

  #New proxy block specifically for ssi routes
  location /ssi {
    proxy_pass http://staging;
  }

  location / {
    ssi on;

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_cache one; #caching
    proxy_cache_key sfs$request_uri$scheme; #caching

    proxy_http_version 1.1;
    proxy_pass http://staging/; #points to the upstream staging
  }
}

经过进一步调查,问题似乎是页面实际上是反复将自身插入到 ssi 包含中。几乎就像包含整个页面(其中也有一个包含)并继续递归地包含新标记一样。

我认为通过将 ssi 请求移出缓存块设置可以缓解这个问题,但我不完全确定为什么。

答案1

我找到了答案。

在之前的配置中,我已将缓存设置为$request_uri。这意味着 nginx 将根据以下条件来归档和获取缓存:传入请求。服务器端包含使其他请求,但是由于缓存基于传入的 uri,它最终会获取主页本身,从而重复插入自身。

通过使用$uri而不是$request_uringinx 将尊重重写和 ssi 请求,从而通过适当的命名空间(在本例中是应用程序定义的 ssi 路由)进行缓存和获取。

以下是有关 nginx 变量的更多信息

相关内容