Подтвердить что ты не робот

Как управлять лаком и браузером с помощью Cache-Control: максимальный заголовок в среде Rails?

Недавно я добавил экземпляр Varnish в стек приложений Rails. Лак в его конфигурации по умолчанию можно убедиться в кэшировании определенного ресурса с помощью заголовка Cache-Control следующим образом:

Cache-Control: max-age=86400, public=true

Я достиг этого, используя оператор expires_in в моих контроллерах:

def index
  expires_in 24.hours, public: true
  respond_with 'some content'
end

Это сработало хорошо. Я не ожидал, что заголовок Cache-Control ТАКЖЕ влияет на браузер. Это приводит к тому, что оба - лак и мой браузер пользователей кешируют определенный ресурс. Ресурс очищается от лака правильно, но браузер не пытается запросить его снова, если не достигнут максимальный возраст.

Так что, интересно, я должен использовать "expires_in" в сочетании с Varnish вообще? Я мог бы фильтровать заголовок Cache-Control в экземпляре Nginx или Apache перед Varnish, но это кажется странным.

Может кто-нибудь просветить меня?

Отношения Felix

4b9b3361

Ответ 1

Это действительно очень хороший и действительный вопрос, и очень общий с обратными прокси.

Проблема заключается в том, что существует только одно свойство Cache-Control и оно предназначено для клиентского браузера (частный кеш) и/или прокси-сервера (общий кэш). Если вы не хотите, чтобы сторонние прокси-серверы кэшировали ваш контент вообще и хотите, чтобы каждый запрос был подан вашим лаком (или вашим backend-сервером Rails), вы должны отправить соответствующий заголовок Cache-Control из Varnish.

Изменение заголовка Cache-Control, отправленного сервером, подробно обсуждается на https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching

Вы можете подойти к решению с двух разных углов. Если вы хотите определить максимальный возраст на своем сервере Rails, например, чтобы указать различные TTL для разных объектов, вы можете использовать метод, описанный в ссылке выше.

Другое решение - не отправлять заголовки Cache-Control вообще из бэкэнд, а вместо этого определять желаемые TTL для объектов в лаке vcl_fetch(). Это подход, который мы предприняли.

У нас есть TTL по умолчанию, равный 600 секундам в лаке, и укажите более длинные TTL для страниц, которые явно явно очищаются при внесении изменений. Здесь наше текущее определение vcl_fetch():

sub vcl_fetch {
  if (req.http.Host ~ "(forum|discus)") {
    # Forum pages are purged explicitly, so cache them for 48h
    set beresp.ttl = 48h;
  }

  if (req.url ~ "^/software/") {
    # Software pages are purged explicitly, so cache them for 48h
    set beresp.ttl = 48h;
  }

  if (req.url ~ "^/search/forum_search_results" ) {
    # We don't want forum search results to be cached for longer than 5 minutes
    set beresp.ttl = 300s;
  }

  if(req.url == "/robots.txt") {
    # Robots.txt is updated rarely and should be cached for 4 days
    # Purge manually as required
    set beresp.ttl = 96h;
  }

  if(beresp.status == 404) {
    # Cache 404 responses for 15 seconds
    set beresp.http.Cache-Control = "max-age=15";
    set beresp.ttl = 15s;
    set beresp.grace = 15s;
  }
}

В нашем случае мы не отправляем заголовки Cache-Control вообще с серверов веб-сервера.