Мне было интересно, есть ли способ контролировать время жизни перенаправлений в Nginx?
Мы бы хотели кэшировать 301 редирект в CDN на определенное время, скажем, 20 минут, и CDN управляется стандартными заголовками кеширования. По умолчанию для перенаправления Nginx нет директив Cache-control или Expires. Это может привести к тому, что перенаправление будет кешироваться на очень долгое время. Имея определенное время жизни перенаправления, система может иметь шанс исправить себя, зная, что даже «постоянные» перенаправления время от времени меняются.
Другое дело, что эти перенаправления включены из блока Server, который, согласно спецификации nginx, должен оцениваться перед местоположениями.
Я пробовал добавить add_header Cache-Control «max-age = 1200, public»; в конец файла перенаправления, но проблема в том, что Cache-control добавляется дважды - сначала идет, скажем, из внутреннего скрипта, а второй добавляется директивой add_header ..
В Apache есть трюк с переменной окружения для управления заголовками при перезаписи:
RewriteRule / taxonomy / term / (\ d +) / feed / taxonomy / term / $ 1 [R = 301, E = expire: 1] Заголовок всегда устанавливает Cache-Control "store, max-age = 1200" env = expire
Но я не уверен, как это сделать в Nginx.
Вы пробовали использовать флаги Cache-Control в своей конфигурации nginx?
Пример конфигурации:
upstream yourappserver{
server 0.0.0.0:6677;
}
proxy_cache_path /tmp/cache levels=1:2 keys_zone=my-test-cache:8m max_size=5000m inactive=300m;
server {
listen 80;
server_name your.domain.tld;
root /path/to/the/document/root/;
access_log /var/log/nginx/access.log;
location / {
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_cache my-test-cache;
proxy_cache_valid 200 404 1m;
proxy_cache_valid 302 20m;
proxy_cache_use_stale error timeout invalid_header updating;
proxy_redirect off;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://yourappserver;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Я думаю, вы ищете именно этот фрагмент конфигурации
proxy_cache_valid 302 20m;
Я тоже использую «трюк с переменной окружения», чтобы сделать это в Apache, и искал эквивалентный метод в nginx. Прошло несколько лет с тех пор, как этот вопрос был впервые задан, поэтому с тех пор все могло измениться, но я нашел способ установить время жизни по умолчанию для перенаправлений в nginx 1.14.
В server
блок, вы можете эффективно установить новое значение по умолчанию Cache-Control
и Expires
значения заголовка для всех 301 редиректов с помощью переменной карты для установки значения expires
директива на основе кода статуса возврата ($status
). При желании это новое значение по умолчанию может быть переопределено в более конкретных location
блоки где необходимо. В качестве дополнительного бонуса вам не нужно повторно указывать переменную среды при каждом перенаправлении, как в Apache.
Вот пример, иллюстрирующий это, когда все HTTP-запросы обновляются до HTTPS с использованием «постоянных» 301 редиректов, которые длятся всего час. Исключение сделано для URI с префиксом /override
, где 301 действительно остается навсегда.
map $status $expires {
default off;
301 1h;
}
server {
listen 80 default_server;
server_name _;
expires $expires;
location /override {
return 301 https://$host/somewhere;
expires off;
}
location / {
return 301 https://$host$request_uri;
}
}
Это дает ожидаемые значения заголовка:
$ curl -I http://localhost
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 11 Jun 2020 01:01:43 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://localhost/
Expires: Thu, 11 Jun 2020 02:01:43 GMT
Cache-Control: max-age=3600
$ curl -I http://localhost/override
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 11 Jun 2020 01:01:49 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://localhost/somewhere