Назад | Перейти на главную страницу

Лак не работает с последними изменениями

Я новичок в Varnish и вообще в обратных прокси. Я тестирую Varnish в приложении, которое работает как блог, где у меня есть страница с «updated_at», которая изменяется после обновления страницы. Как следствие, я решил, что моя стратегия кеширования должна основываться на последнем измененном заголовке. Причина в том, что пользователь хочет увидеть изменение сразу после изменения страницы в бэк-офисе.

В дополнение к этому я понял, что могу добавить s-maxage с must-revalidate в cache-control, чтобы, если последнее изменение не изменилось, Varnish даже не попытался бы сделать новый запрос.

Я также добавил срок действия для браузера, чтобы был кеш клиента. В результате браузер даже не попросит varnish снова сделать запрос к Apache.

Однако я заметил, что s-maxage для управления кешем имеет приоритет над последним измененным, даже если требуется повторная проверка. Более того, даже если я не добавлю кэш-контроль, «последнее изменение» не работает. Varnish использует ttl по умолчанию, и ничего не происходит. Что я делаю не так?

Я использую Symfony, и это заголовки:

$response = new Response();
$response->setPublic();

// expiration model for the browser cache (EXPIRE)
// the browser will only make a new request to Varnish again after ten minutes (600 seconds)
$date = new \DateTime();
$date->modify('+600 seconds');
$response->setExpires($date);

// expiration model for Varnish (CACHE-CONTROL)
// Varnish will only make a new request to Apache again after one hour (3600 seconds)
// The must-revalidate tells Varnish to do this request before serving the files after one hour (it's already de default behaviour)
// cache-control has priority over expire
//$response->setSharedMaxAge(3600);
$response->headers->addCacheControlDirective('must-revalidate', true);

// validation model for varnish (LAST-MODIFIED)
// Varnish will only make a new request to Apache again if the updated_at of the page changed even if the expiration time is ended
$response->setLastModified($page->getUpdatedAt());

// if the response didn't change, stop here
if ($response->isNotModified($request)) {
    return $response;
}

Вот мои заголовки в первый раз, когда у меня MISS, и во второй раз, когда у меня HIT. Тогда не имеет значения, если последние измененные изменения всегда совпадают с заголовками этого второго. (Мой кешер браузера отключен, поэтому у меня 200 вместо 304)

первый запрос

второй запрос

Не существует такой вещи, как «Последнее изменение не работает». Этот заголовок просто указывает дату последнего изменения ресурса. После этого клиенты могут выдавать запросы «если не было изменено с», но это не важно для вашей ситуации.

Естественно, что последующие запросы будут возвращать точно такие же заголовки. Объекты в Varnish кэшируются, включая информацию заголовков. Поэтому, когда Varnish извлекает кешированную запись, он вернет ее точную копию.

Понимая это

Вы имеете дело с двумя кешами одновременно: Varnish и кешем браузера. У вас есть только один набор заголовков HTTP на запрос. Вы не можете указать один HTTP Expires для браузера, а затем другой только для Varnish.

Поэтому, если вы хотите кэшировать вещи по-другому (а вы это делаете), одно решение - это настройка beresp.ttl в Varnish на количество времени, в течение которого вы хотите расслабить серверную часть PHP, то есть: 24 часа.

Где-то в VCL:

sub vcl_backend_response {
    # A TTL of 24h
    # set beresp.ttl = 24h;
}

Затем, учитывая, что вы сохраняете свой существующий PHP-код, Varnish кэширует первый запрос на страницу на 24 часа и делает его кешируемым браузерами на 10 минут.

После обновления статьи вам необходимо очистить кеш Varnish, также известный как Cache Invalidation. См. Некоторое представление о эта страница (прокрутите вниз).

Причина в том, что пользователь хочет увидеть изменение сразу после изменения страницы в бэк-офисе.

И все же вы хотите, чтобы у них был 10-минутный кеш браузера :)