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 include. Почти как если бы включение включало в себя целую страницу, которая также имела включение и продолжала рекурсивно включать новую разметку.

Я думаю, что при перемещении запросов ssi за пределы настройки блока кэширования это было смягчено, но я не совсем уверен, почему.

1 ответ

Решение

Я обнаружил ответ.

В предыдущем конфиге у меня было установлено кэширование $request_uri, Это означает, что nginx будет регистрировать и извлекать кэши на основе входящего запроса. Серверная сторона include делает еще один запрос, но, поскольку кеширование основано на входящем URI, оно в конечном итоге получает саму главную страницу, таким образом, вставляя себя повторно.

Используя $uri вместо $request_uri nginx будет уважать запросы на переписывание и ssi, таким образом, кэшируя и выбирая через соответствующие пространства имен (в этом случае определенные ssi маршруты приложения).

Вот больше информации о переменных nginx

Другие вопросы по тегам