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

лак доставляет случайно пустые страницы

У нас возникла проблема с настройкой, когда Varnish начал выдавать пустые страницы. Мы завершаем ssl перед лаком и используем установку apache2.4 + php-fpm поверх fcgi за ним.

На первый взгляд казалось, что страницы находятся только в устаревшем приложении, в котором мы обречены использовать php5.6, поэтому мы можем получить белые страницы гибели. Но эти ошибки случались случайно. Также были затронуты приложения php7.2.

Следующие предположения касались недавних изменений в apache с нашей стороны (тип мьютекса). Это тоже оказалось неправильным.

Включение кеширования решило проблему, но не решило ее.

Все поиски в Интернете намекали на корреляцию между Content-Encoding: chunked и неправильной версией http, но, проверяя это, мы используем http / 1.1 до и после лака. Также у нас возникла эта проблема случайно (~ 0,6% страниц).

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

Решение пришло ко мне во время тестирования:

Я тестировал на нескольких машинах, используя curl и менее. Но иногда я использовал -I, таким образом инициируя запрос HEAD. Оказалось, что запрос HEAD обрабатывается как запрос GET с точки зрения кеширования (тот же ключ кеша), но серверная часть просто отвечает без тела на запросы заголовка. Таким образом, вы получаете кеш-объекты без тела, которые также запускают HIT для запросов GET.

Я просто добавил эту строку в vcl_hash, и проблема исчезла:

  hash_data(req.method); // cache HEAD requests seperately

надеюсь, что это поможет кому-то еще пропустить 2 недели отладки.

Как обрабатывается лак HEAD Запросы

Поведение Varnish по умолчанию - принять HEAD запрос и превратить его в GET запрос.

Ответ сохраняется в кеше, но полезная нагрузка удаляется перед возвратом клиенту.

Это сделано намеренно из соображений эффективности и не нарушает RFC. Вывод должен быть идентичным.

Varnish не добавляет вариант кеширования на основе метода запроса. Так как HEAD превращается в GET, это изменение не требуется.

Как обойти это поведение по умолчанию

В вашем конкретном случае вы выполнили оптимизацию на уровне источника для обработки HEAD Запросы. По-видимому, получение чистого и неподдельного HEAD запросы на происхождение имеет значение.

Чтобы добиться этого и обойти поведение по умолчанию, есть 2 распространенных способа:

Вы можете явно установить метод запроса на HEAD в vcl_backend_fetch:

sub vcl_recv {
    set req.http.method = req.method;
}

sub vcl_hash {
    hash_data(req.http.method);
}

sub vcl_backend_fetch {
    if(bereq.http.method == "HEAD") {
        set bereq.method = "GET";
    }
    unset bereq.http.method;
}

Вы можете обойти кеш:

sub vcl_recv {
    if(req.method == "HEAD") {
        return(pass);
    }
}

Первое решение в вашем случае, вероятно, лучше второго.

Что-то происходит в вашем VCL

Хотя вы утверждаете, что нет логики VCL, которая удерживает HEAD запросы нетронутые, я подозреваю, что что-то происходит в вашем VCL.

Я хотел бы увидеть ваш полный файл VCL и попробовать его сам. Не стесняйтесь редактировать любые конфиденциальные данные.

Я согласен с решением вашей проблемы.

Хотя мне трудно поверить, что ваша установка Varnish сохраняет HEAD запросы без каких-либо специальных VCL, то решение, которое вы предлагаете, является действительным.

Создание варианта кеша для каждого метода запроса - хороший способ решить вашу проблему.

Независимо от того, есть ли у вас специальный VCL для HEAD запросов, это поведение, которое вам нужно, чтобы удовлетворить ваш исходный сервер. Я не собираюсь с этим спорить.

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

С нетерпением жду этого файла VCL и спасибо за ваш вклад.