![第一次请求后,Nginx ssi 与 proxy_cache 挂起](https://linux22.com/image/607266/%E7%AC%AC%E4%B8%80%E6%AC%A1%E8%AF%B7%E6%B1%82%E5%90%8E%EF%BC%8CNginx%20ssi%20%E4%B8%8E%20proxy_cache%20%E6%8C%82%E8%B5%B7.png)
我正在使用 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_uri
nginx 将尊重重写和 ssi 请求,从而通过适当的命名空间(在本例中是应用程序定义的 ssi 路由)进行缓存和获取。